aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFathi Boudra <fathi.boudra@linaro.org>2013-03-30 17:41:03 +0200
committerFathi Boudra <fathi.boudra@linaro.org>2013-03-30 17:41:03 +0200
commitf4243e63fd6e9588757edb1cca3cc3d88bc22faf (patch)
treeb843d8471cf68b3975b6f740615769c54da3220b
parent3dd5a70c47fe95276537f8ca544d52b135e879bf (diff)
Imported Upstream version 2.00+bzr4617+20130130upstream/2.00+bzr4617+20130130
-rw-r--r--.bzr/README3
-rw-r--r--.bzr/branch-format1
-rw-r--r--.bzr/branch/branch.conf1
-rw-r--r--.bzr/branch/format1
-rw-r--r--.bzr/branch/last-revision1
-rw-r--r--.bzr/branch/tags1
-rw-r--r--.bzr/checkout/conflicts1
-rw-r--r--.bzr/checkout/dirstatebin322100 -> 0 bytes
-rw-r--r--.bzr/checkout/format1
-rw-r--r--.bzr/checkout/views0
-rw-r--r--.bzr/repository/format1
-rw-r--r--.bzr/repository/indices/21eed38863b95e047c05b09028452571.cixbin1312577 -> 0 bytes
-rw-r--r--.bzr/repository/indices/21eed38863b95e047c05b09028452571.iixbin272536 -> 0 bytes
-rw-r--r--.bzr/repository/indices/21eed38863b95e047c05b09028452571.rixbin275485 -> 0 bytes
-rw-r--r--.bzr/repository/indices/21eed38863b95e047c05b09028452571.sixbin123450 -> 0 bytes
-rw-r--r--.bzr/repository/indices/21eed38863b95e047c05b09028452571.tixbin1287938 -> 0 bytes
-rw-r--r--.bzr/repository/pack-names6
-rw-r--r--.bzr/repository/packs/21eed38863b95e047c05b09028452571.packbin14715352 -> 0 bytes
-rw-r--r--.bzrignore176
-rw-r--r--ChangeLog672
-rw-r--r--Makefile.util.def5
-rw-r--r--acinclude.m46
-rwxr-xr-xautogen.sh16
-rw-r--r--conf/Makefile.common16
-rw-r--r--configure.ac32
-rw-r--r--docs/grub.texi285
-rw-r--r--docs/man/grub-bios-setup.h2m2
-rw-r--r--docs/man/grub-install.h2m1
-rw-r--r--docs/man/grub-mkimage.h2m1
-rw-r--r--docs/man/grub-sparc64-setup.h2m2
-rw-r--r--grub-core/Makefile.core.def55
-rw-r--r--grub-core/bus/cs5536.c45
-rw-r--r--grub-core/bus/emu/pci.c4
-rw-r--r--grub-core/bus/pci.c4
-rw-r--r--grub-core/bus/usb/ehci.c12
-rw-r--r--grub-core/bus/usb/emu/usb.c4
-rw-r--r--grub-core/bus/usb/ohci.c12
-rw-r--r--grub-core/bus/usb/uhci.c11
-rw-r--r--grub-core/bus/usb/usb.c120
-rw-r--r--grub-core/bus/usb/usbhub.c4
-rw-r--r--grub-core/bus/usb/usbtrans.c20
-rw-r--r--grub-core/commands/acpi.c55
-rw-r--r--grub-core/commands/arc/lsdev.c18
-rw-r--r--grub-core/commands/efi/fixvideo.c8
-rw-r--r--grub-core/commands/hashsum.c2
-rw-r--r--grub-core/commands/i386/pc/play.c109
-rw-r--r--grub-core/commands/i386/pc/sendkey.c65
-rw-r--r--grub-core/commands/legacycfg.c21
-rw-r--r--grub-core/commands/loadenv.c15
-rw-r--r--grub-core/commands/ls.c231
-rw-r--r--grub-core/commands/lsmmap.c31
-rw-r--r--grub-core/commands/lspci.c8
-rw-r--r--grub-core/commands/pcidump.c165
-rw-r--r--grub-core/commands/search.c398
-rw-r--r--grub-core/commands/setpci.c11
-rw-r--r--grub-core/commands/test.c305
-rw-r--r--grub-core/commands/usbtest.c4
-rw-r--r--grub-core/commands/verify.c787
-rw-r--r--grub-core/commands/wildcard.c242
-rw-r--r--grub-core/disk/ahci.c13
-rw-r--r--grub-core/disk/arc/arcdisk.c36
-rw-r--r--grub-core/disk/ata.c118
-rw-r--r--grub-core/disk/cryptodisk.c13
-rw-r--r--grub-core/disk/diskfilter.c116
-rw-r--r--grub-core/disk/efi/efidisk.c69
-rw-r--r--grub-core/disk/host.c4
-rw-r--r--grub-core/disk/i386/pc/biosdisk.c15
-rw-r--r--grub-core/disk/ieee1275/nand.c7
-rw-r--r--grub-core/disk/ieee1275/ofdisk.c4
-rw-r--r--grub-core/disk/ldm.c50
-rw-r--r--grub-core/disk/loopback.c9
-rw-r--r--grub-core/disk/memdisk.c4
-rw-r--r--grub-core/disk/pata.c12
-rw-r--r--grub-core/disk/scsi.c81
-rw-r--r--grub-core/disk/uboot/ubootdisk.c9
-rw-r--r--grub-core/disk/usbms.c5
-rw-r--r--grub-core/efiemu/mm.c97
-rw-r--r--grub-core/font/font.c133
-rw-r--r--grub-core/fs/affs.c201
-rw-r--r--grub-core/fs/bfs.c95
-rw-r--r--grub-core/fs/btrfs.c106
-rw-r--r--grub-core/fs/cpio.c5
-rw-r--r--grub-core/fs/ext2.c121
-rw-r--r--grub-core/fs/fat.c16
-rw-r--r--grub-core/fs/fshelp.c307
-rw-r--r--grub-core/fs/hfs.c9
-rw-r--r--grub-core/fs/hfsplus.c60
-rw-r--r--grub-core/fs/iso9660.c56
-rw-r--r--grub-core/fs/jfs.c5
-rw-r--r--grub-core/fs/minix.c13
-rw-r--r--grub-core/fs/nilfs2.c110
-rw-r--r--grub-core/fs/ntfs.c248
-rw-r--r--grub-core/fs/ntfscomp.c55
-rw-r--r--grub-core/fs/reiserfs.c54
-rw-r--r--grub-core/fs/romfs.c51
-rw-r--r--grub-core/fs/sfs.c137
-rw-r--r--grub-core/fs/squash4.c57
-rw-r--r--grub-core/fs/udf.c109
-rw-r--r--grub-core/fs/ufs.c5
-rw-r--r--grub-core/fs/xfs.c140
-rw-r--r--grub-core/fs/zfs/zfs.c488
-rw-r--r--grub-core/gfxmenu/font.c2
-rw-r--r--grub-core/gnulib/stdio.in.h6
-rw-r--r--grub-core/io/bufio.c8
-rw-r--r--grub-core/io/gzio.c6
-rw-r--r--grub-core/io/lzopio.c5
-rw-r--r--grub-core/io/xzio.c9
-rw-r--r--grub-core/kern/arm/uboot/startup.S2
-rw-r--r--grub-core/kern/corecmd.c25
-rw-r--r--grub-core/kern/device.c145
-rw-r--r--grub-core/kern/disk.c11
-rw-r--r--grub-core/kern/efi/mm.c53
-rw-r--r--grub-core/kern/elf.c373
-rw-r--r--grub-core/kern/emu/hostdisk.c6
-rw-r--r--grub-core/kern/emu/hostfs.c5
-rw-r--r--grub-core/kern/file.c2
-rw-r--r--grub-core/kern/fs.c21
-rw-r--r--grub-core/kern/i386/coreboot/init.c68
-rw-r--r--grub-core/kern/i386/coreboot/mmap.c85
-rw-r--r--grub-core/kern/i386/multiboot_mmap.c4
-rw-r--r--grub-core/kern/i386/pc/init.c61
-rw-r--r--grub-core/kern/i386/pc/mmap.c14
-rw-r--r--grub-core/kern/i386/pit.c35
-rw-r--r--grub-core/kern/i386/qemu/mmap.c14
-rw-r--r--grub-core/kern/ieee1275/init.c124
-rw-r--r--grub-core/kern/ieee1275/mmap.c4
-rw-r--r--grub-core/kern/mips/arc/init.c18
-rw-r--r--grub-core/kern/mips/loongson/init.c80
-rw-r--r--grub-core/kern/mips/qemu_mips/init.c4
-rw-r--r--grub-core/kern/misc.c17
-rw-r--r--grub-core/kern/parser.c74
-rw-r--r--grub-core/kern/partition.c156
-rw-r--r--grub-core/kern/rescue_parser.c6
-rw-r--r--grub-core/kern/rescue_reader.c7
-rw-r--r--grub-core/kern/term.c4
-rw-r--r--grub-core/kern/uboot/hw.c5
-rw-r--r--grub-core/kern/vga_init.c61
-rw-r--r--grub-core/lib/arg.c58
-rw-r--r--grub-core/lib/arm/libgcc.S72
-rw-r--r--grub-core/lib/crc.c31
-rw-r--r--grub-core/lib/crc64.c31
-rw-r--r--grub-core/lib/crypto.c34
-rw-r--r--grub-core/lib/dtc/libfdt/fdt.c287
-rw-r--r--grub-core/lib/dtc/libfdt/fdt.h70
-rw-r--r--grub-core/lib/dtc/libfdt/fdt_ro.c794
-rw-r--r--grub-core/lib/dtc/libfdt/fdt_rw.c621
-rw-r--r--grub-core/lib/dtc/libfdt/fdt_strerror.c52
-rw-r--r--grub-core/lib/dtc/libfdt/fdt_sw.c287
-rw-r--r--grub-core/lib/dtc/libfdt/fdt_wip.c77
-rw-r--r--grub-core/lib/dtc/libfdt/libfdt.h208
-rw-r--r--grub-core/lib/dtc/libfdt/libfdt_env.h14
-rw-r--r--grub-core/lib/dtc/libfdt/libfdt_internal.h35
-rw-r--r--grub-core/lib/i386/relocator.c2
-rw-r--r--grub-core/lib/i386/relocator16.S5
-rw-r--r--grub-core/lib/ieee1275/cmos.c82
-rw-r--r--grub-core/lib/ieee1275/datetime.c27
-rw-r--r--grub-core/lib/ieee1275/relocator.c102
-rw-r--r--grub-core/lib/libgcrypt/cipher/ChangeLog94
-rw-r--r--grub-core/lib/libgcrypt/cipher/Makefile.am82
-rw-r--r--grub-core/lib/libgcrypt/cipher/Manifest73
-rw-r--r--grub-core/lib/libgcrypt/cipher/ac.c2
-rw-r--r--grub-core/lib/libgcrypt/cipher/cipher.c737
-rw-r--r--grub-core/lib/libgcrypt/cipher/crc.c1
-rw-r--r--grub-core/lib/libgcrypt/cipher/des.c2
-rw-r--r--grub-core/lib/libgcrypt/cipher/dsa.c1
-rw-r--r--grub-core/lib/libgcrypt/cipher/ecc.c23
-rw-r--r--grub-core/lib/libgcrypt/cipher/md.c19
-rw-r--r--grub-core/lib/libgcrypt/cipher/md4.c1
-rw-r--r--grub-core/lib/libgcrypt/cipher/md5.c1
-rw-r--r--grub-core/lib/libgcrypt/cipher/primegen.c4
-rw-r--r--grub-core/lib/libgcrypt/cipher/pubkey.c12
-rw-r--r--grub-core/lib/libgcrypt/cipher/rfc2268.c2
-rw-r--r--grub-core/lib/libgcrypt/cipher/rmd160.c1
-rw-r--r--grub-core/lib/libgcrypt/cipher/rsa.c32
-rw-r--r--grub-core/lib/libgcrypt/cipher/sha1.c1
-rw-r--r--grub-core/lib/libgcrypt/cipher/sha256.c91
-rw-r--r--grub-core/lib/libgcrypt/cipher/sha512.c98
-rw-r--r--grub-core/lib/libgcrypt/cipher/test-getrusage.c105
-rw-r--r--grub-core/lib/libgcrypt/cipher/tiger.c102
-rw-r--r--grub-core/lib/libgcrypt/cipher/twofish.c2
-rw-r--r--grub-core/lib/libgcrypt/cipher/whirlpool.c1
-rw-r--r--grub-core/lib/libgcrypt/mpi/ChangeLog-2011831
-rw-r--r--grub-core/lib/libgcrypt/mpi/Makefile.am177
-rw-r--r--grub-core/lib/libgcrypt/mpi/Manifest41
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/README53
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/distfiles11
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S124
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S122
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S90
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S97
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S95
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S118
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S124
-rw-r--r--grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S159
-rw-r--r--grub-core/lib/libgcrypt/mpi/amd64/distfiles7
-rw-r--r--grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S63
-rw-r--r--grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S77
-rw-r--r--grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S65
-rw-r--r--grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S107
-rw-r--r--grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S66
-rw-r--r--grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S80
-rw-r--r--grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S61
-rw-r--r--grub-core/lib/libgcrypt/mpi/config.links360
-rw-r--r--grub-core/lib/libgcrypt/mpi/ec.c708
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/Manifest29
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/distfiles11
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h10
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c65
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c68
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c62
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c68
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c68
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c67
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c66
-rw-r--r--grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c133
-rw-r--r--grub-core/lib/libgcrypt/mpi/hppa/README84
-rw-r--r--grub-core/lib/libgcrypt/mpi/hppa/distfiles7
-rw-r--r--grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S70
-rw-r--r--grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S77
-rw-r--r--grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S73
-rw-r--r--grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S78
-rw-r--r--grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S297
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/Manifest28
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/distfiles10
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S116
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S94
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S84
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S86
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S86
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S97
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S117
-rw-r--r--grub-core/lib/libgcrypt/mpi/i386/syntax.h68
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/Manifest27
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/README26
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/distfiles10
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S135
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S229
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S89
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S93
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S93
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S228
-rw-r--r--grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S142
-rw-r--r--grub-core/lib/libgcrypt/mpi/longlong.h1578
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/Manifest25
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/distfiles9
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest23
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles4
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S104
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S94
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S97
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S92
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S164
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S162
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S91
-rw-r--r--grub-core/lib/libgcrypt/mpi/m68k/syntax.h185
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/Manifest28
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/README23
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/distfiles11
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h10
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S124
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S97
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S89
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S101
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S101
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S95
-rw-r--r--grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S125
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-add.c235
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-bit.c364
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-cmp.c107
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-div.c355
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-gcd.c51
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-inline.c35
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-inline.h154
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-internal.h277
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-inv.c267
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-mod.c184
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-mpow.c223
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-mul.c212
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-pow.c324
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpi-scan.c130
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpicoder.c750
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpih-div.c533
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpih-mul.c528
-rw-r--r--grub-core/lib/libgcrypt/mpi/mpiutil.c460
-rw-r--r--grub-core/lib/libgcrypt/mpi/pa7100/Manifest22
-rw-r--r--grub-core/lib/libgcrypt/mpi/pa7100/distfiles4
-rw-r--r--grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S96
-rw-r--r--grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S92
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/README115
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/distfiles3
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles2
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S457
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S453
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles5
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S91
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S96
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S136
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S127
-rw-r--r--grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S112
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/Manifest27
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/distfiles8
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/mpih-add1.S87
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S64
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S115
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S130
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S135
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S64
-rw-r--r--grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S88
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/Manifest28
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/distfiles10
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S136
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S198
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S120
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S127
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S130
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S131
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S133
-rw-r--r--grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h75
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32/Manifest24
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32/distfiles6
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S239
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S97
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S93
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32/udiv.S195
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest23
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles5
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S109
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S132
-rw-r--r--grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S67
-rw-r--r--grub-core/lib/libgcrypt/mpi/supersparc/Manifest21
-rw-r--r--grub-core/lib/libgcrypt/mpi/supersparc/distfiles3
-rw-r--r--grub-core/lib/libgcrypt/mpi/supersparc/udiv.S118
-rw-r--r--grub-core/lib/libgcrypt/src/ChangeLog-20112398
-rw-r--r--grub-core/lib/libgcrypt/src/Makefile.am143
-rw-r--r--grub-core/lib/libgcrypt/src/Manifest58
-rw-r--r--grub-core/lib/libgcrypt/src/ath.c323
-rw-r--r--grub-core/lib/libgcrypt/src/ath.h92
-rw-r--r--grub-core/lib/libgcrypt/src/cipher-proto.h124
-rw-r--r--grub-core/lib/libgcrypt/src/cipher.h181
-rw-r--r--grub-core/lib/libgcrypt/src/dumpsexp.c766
-rw-r--r--grub-core/lib/libgcrypt/src/fips.c852
-rw-r--r--grub-core/lib/libgcrypt/src/g10lib.h349
-rw-r--r--grub-core/lib/libgcrypt/src/gcrypt-module.h204
-rw-r--r--grub-core/lib/libgcrypt/src/gcrypt.h.in1337
-rw-r--r--grub-core/lib/libgcrypt/src/gcryptrnd.c680
-rw-r--r--grub-core/lib/libgcrypt/src/getrandom.c326
-rw-r--r--grub-core/lib/libgcrypt/src/global.c1112
-rw-r--r--grub-core/lib/libgcrypt/src/hmac256.c795
-rw-r--r--grub-core/lib/libgcrypt/src/hmac256.h36
-rw-r--r--grub-core/lib/libgcrypt/src/hwfeatures.c192
-rw-r--r--grub-core/lib/libgcrypt/src/libgcrypt-config.in189
-rw-r--r--grub-core/lib/libgcrypt/src/libgcrypt.def213
-rw-r--r--grub-core/lib/libgcrypt/src/libgcrypt.m4122
-rw-r--r--grub-core/lib/libgcrypt/src/libgcrypt.vers94
-rw-r--r--grub-core/lib/libgcrypt/src/misc.c298
-rw-r--r--grub-core/lib/libgcrypt/src/missing-string.c54
-rw-r--r--grub-core/lib/libgcrypt/src/module.c212
-rw-r--r--grub-core/lib/libgcrypt/src/mpi.h263
-rw-r--r--grub-core/lib/libgcrypt/src/secmem.c696
-rw-r--r--grub-core/lib/libgcrypt/src/secmem.h39
-rw-r--r--grub-core/lib/libgcrypt/src/sexp.c2033
-rw-r--r--grub-core/lib/libgcrypt/src/stdmem.c242
-rw-r--r--grub-core/lib/libgcrypt/src/stdmem.h32
-rw-r--r--grub-core/lib/libgcrypt/src/types.h128
-rw-r--r--grub-core/lib/libgcrypt/src/versioninfo.rc.in51
-rw-r--r--grub-core/lib/libgcrypt/src/visibility.c1146
-rw-r--r--grub-core/lib/libgcrypt/src/visibility.h565
-rw-r--r--grub-core/lib/libgcrypt_wrap/cipher_wrap.h58
-rw-r--r--grub-core/lib/libgcrypt_wrap/mem.c133
-rw-r--r--grub-core/lib/posix_wrap/stdio.h3
-rw-r--r--grub-core/lib/posix_wrap/string.h17
-rw-r--r--grub-core/lib/posix_wrap/sys/types.h15
-rw-r--r--grub-core/lib/relocator.c143
-rw-r--r--grub-core/lib/xzembed/xz_dec_lzma2.c4
-rw-r--r--grub-core/lib/xzembed/xz_dec_stream.c10
-rw-r--r--grub-core/loader/efi/chainloader.c48
-rw-r--r--grub-core/loader/i386/bsd.c140
-rw-r--r--grub-core/loader/i386/linux.c259
-rw-r--r--grub-core/loader/i386/multiboot_mbi.c74
-rw-r--r--grub-core/loader/i386/pc/freedos.c61
-rw-r--r--grub-core/loader/i386/pc/plan9.c513
-rw-r--r--grub-core/loader/multiboot.c23
-rw-r--r--grub-core/loader/multiboot_mbi2.c66
-rw-r--r--grub-core/loader/powerpc/ieee1275/linux.c95
-rw-r--r--grub-core/loader/sparc64/ieee1275/linux.c143
-rw-r--r--grub-core/loader/xnu.c205
-rw-r--r--grub-core/mmap/efi/mmap.c23
-rw-r--r--grub-core/mmap/i386/mmap.c52
-rw-r--r--grub-core/mmap/i386/pc/mmap.c49
-rw-r--r--grub-core/mmap/i386/uppermem.c83
-rw-r--r--grub-core/mmap/mips/uppermem.c58
-rw-r--r--grub-core/mmap/mmap.c388
-rw-r--r--grub-core/net/bootp.c2
-rw-r--r--grub-core/net/net.c4
-rw-r--r--grub-core/normal/charset.c98
-rw-r--r--grub-core/normal/color.c9
-rw-r--r--grub-core/normal/completion.c18
-rw-r--r--grub-core/normal/main.c53
-rw-r--r--grub-core/normal/menu_entry.c444
-rw-r--r--grub-core/normal/menu_text.c24
-rw-r--r--grub-core/normal/term.c187
-rw-r--r--grub-core/partmap/acorn.c6
-rw-r--r--grub-core/partmap/amiga.c6
-rw-r--r--grub-core/partmap/apple.c6
-rw-r--r--grub-core/partmap/bsdlabel.c103
-rw-r--r--grub-core/partmap/dvh.c5
-rw-r--r--grub-core/partmap/gpt.c88
-rw-r--r--grub-core/partmap/msdos.c13
-rw-r--r--grub-core/partmap/plan.c6
-rw-r--r--grub-core/partmap/sun.c5
-rw-r--r--grub-core/partmap/sunpc.c6
-rw-r--r--grub-core/script/execute.c51
-rw-r--r--grub-core/script/lexer.c9
-rw-r--r--grub-core/script/main.c5
-rw-r--r--grub-core/script/script.c6
-rw-r--r--grub-core/term/arc/console.c2
-rw-r--r--grub-core/term/efi/console.c9
-rw-r--r--grub-core/term/emu/console.c4
-rw-r--r--grub-core/term/gfxterm.c8
-rw-r--r--grub-core/term/i386/pc/console.c9
-rw-r--r--grub-core/term/i386/pc/vga_text.c10
-rw-r--r--grub-core/term/ieee1275/console.c2
-rw-r--r--grub-core/term/morse.c129
-rw-r--r--grub-core/term/serial.c2
-rw-r--r--grub-core/term/spkmodem.c141
-rw-r--r--grub-core/term/terminfo.c8
-rw-r--r--grub-core/term/uboot/console.c2
-rw-r--r--grub-core/tests/lib/test.c14
-rw-r--r--grub-core/video/bochs.c46
-rw-r--r--grub-core/video/cirrus.c46
-rw-r--r--grub-core/video/efi_uga.c119
-rw-r--r--grub-core/video/radeon_fuloong2e.c50
-rw-r--r--grub-core/video/sis315pro.c60
-rw-r--r--grub-core/video/sm712.c50
-rw-r--r--include/grub/arc/arc.h7
-rw-r--r--include/grub/arm/linux.h12
-rw-r--r--include/grub/ata.h4
-rw-r--r--include/grub/crypto.h99
-rw-r--r--include/grub/device.h5
-rw-r--r--include/grub/disk.h8
-rw-r--r--include/grub/efiemu/efiemu.h2
-rw-r--r--include/grub/elfload.h11
-rw-r--r--include/grub/err.h3
-rw-r--r--include/grub/file.h27
-rw-r--r--include/grub/fs.h7
-rw-r--r--include/grub/fshelp.h15
-rw-r--r--include/grub/gcry/types.h37
-rw-r--r--include/grub/gcrypt/gpg-error.h32
-rw-r--r--include/grub/gpt_partition.h4
-rw-r--r--include/grub/i386/macho.h5
-rw-r--r--include/grub/i386/pit.h78
-rw-r--r--include/grub/i386/relocator.h1
-rw-r--r--include/grub/kernel.h5
-rw-r--r--include/grub/macho.h1
-rw-r--r--include/grub/memory.h18
-rw-r--r--include/grub/msdos_partition.h4
-rw-r--r--include/grub/normal.h8
-rw-r--r--include/grub/ntfs.h26
-rw-r--r--include/grub/parser.h7
-rw-r--r--include/grub/partition.h11
-rw-r--r--include/grub/pci.h7
-rw-r--r--include/grub/pubkey.h38
-rw-r--r--include/grub/reader.h2
-rw-r--r--include/grub/script_sh.h12
-rw-r--r--include/grub/scsi.h5
-rw-r--r--include/grub/speaker.h47
-rw-r--r--include/grub/symbol.h18
-rw-r--r--include/grub/term.h32
-rw-r--r--include/grub/unicode.h22
-rw-r--r--include/grub/usb.h11
-rw-r--r--include/grub/usbtrans.h2
-rw-r--r--m4/stdio_h.m44
-rw-r--r--tests/util/grub-shell-tester.in2
-rw-r--r--tests/util/grub-shell.in2
-rw-r--r--util/bash-completion.d/grub-completion.bash.in36
-rw-r--r--util/getroot.c76
-rw-r--r--util/grub-install.in20
-rw-r--r--util/grub-kbdcomp.in4
-rw-r--r--util/grub-mkconfig.in9
-rw-r--r--util/grub-mkconfig_lib.in6
-rw-r--r--util/grub-mkimage.c54
-rw-r--r--util/grub-mknetdir.in4
-rw-r--r--util/grub-mkrescue.in4
-rw-r--r--util/grub-mkstandalone.in4
-rw-r--r--util/grub-mount.c142
-rw-r--r--util/grub-probe.c2
-rw-r--r--util/grub-reboot.in6
-rw-r--r--util/grub-script-check.c121
-rw-r--r--util/grub-set-default.in6
-rw-r--r--util/grub-setup.c125
-rw-r--r--util/grub.d/00_header.in2
-rw-r--r--util/grub.d/10_kfreebsd.in10
-rw-r--r--util/ieee1275/ofpath.c4
-rw-r--r--util/import_gcry.py211
-rw-r--r--util/import_gcrypth.sed15
-rw-r--r--util/powerpc/ieee1275/grub-mkrescue.in4
-rw-r--r--util/spkmodem-recv.c115
497 files changed, 48656 insertions, 7171 deletions
diff --git a/.bzr/README b/.bzr/README
deleted file mode 100644
index f82dc1c..0000000
--- a/.bzr/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This is a Bazaar control directory.
-Do not change any files in this directory.
-See http://bazaar.canonical.com/ for more information about Bazaar.
diff --git a/.bzr/branch-format b/.bzr/branch-format
deleted file mode 100644
index 9eb09b7..0000000
--- a/.bzr/branch-format
+++ /dev/null
@@ -1 +0,0 @@
-Bazaar-NG meta directory, format 1
diff --git a/.bzr/branch/branch.conf b/.bzr/branch/branch.conf
deleted file mode 100644
index ac398d8..0000000
--- a/.bzr/branch/branch.conf
+++ /dev/null
@@ -1 +0,0 @@
-parent_location = http://bazaar.launchpad.net/~leif-lindholm/linaro-grub/arm-uboot/
diff --git a/.bzr/branch/format b/.bzr/branch/format
deleted file mode 100644
index dc392f4..0000000
--- a/.bzr/branch/format
+++ /dev/null
@@ -1 +0,0 @@
-Bazaar Branch Format 7 (needs bzr 1.6)
diff --git a/.bzr/branch/last-revision b/.bzr/branch/last-revision
deleted file mode 100644
index 68f77a2..0000000
--- a/.bzr/branch/last-revision
+++ /dev/null
@@ -1 +0,0 @@
-4615 leif.lindholm@linaro.org-20121214130050-zqwt2roanb508g2f
diff --git a/.bzr/branch/tags b/.bzr/branch/tags
deleted file mode 100644
index 3aa3d02..0000000
--- a/.bzr/branch/tags
+++ /dev/null
@@ -1 +0,0 @@
-d4:1.9949:phcoder@gmail.com-20110514204953-z0pozky4dagt6ff44:2.0049:phcoder@gmail.com-20120628000636-gujxzbli71mifg6g15:initial-release53:leif.lindholm@arm.com-20121207132742-lb2l9tbw9t1axzeee \ No newline at end of file
diff --git a/.bzr/checkout/conflicts b/.bzr/checkout/conflicts
deleted file mode 100644
index 0dc2d3a..0000000
--- a/.bzr/checkout/conflicts
+++ /dev/null
@@ -1 +0,0 @@
-BZR conflict list format 1
diff --git a/.bzr/checkout/dirstate b/.bzr/checkout/dirstate
deleted file mode 100644
index 7ff7af2..0000000
--- a/.bzr/checkout/dirstate
+++ /dev/null
Binary files differ
diff --git a/.bzr/checkout/format b/.bzr/checkout/format
deleted file mode 100644
index e0261c7..0000000
--- a/.bzr/checkout/format
+++ /dev/null
@@ -1 +0,0 @@
-Bazaar Working Tree Format 6 (bzr 1.14)
diff --git a/.bzr/checkout/views b/.bzr/checkout/views
deleted file mode 100644
index e69de29..0000000
--- a/.bzr/checkout/views
+++ /dev/null
diff --git a/.bzr/repository/format b/.bzr/repository/format
deleted file mode 100644
index b200528..0000000
--- a/.bzr/repository/format
+++ /dev/null
@@ -1 +0,0 @@
-Bazaar repository format 2a (needs bzr 1.16 or later)
diff --git a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.cix b/.bzr/repository/indices/21eed38863b95e047c05b09028452571.cix
deleted file mode 100644
index 8802692..0000000
--- a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.cix
+++ /dev/null
Binary files differ
diff --git a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.iix b/.bzr/repository/indices/21eed38863b95e047c05b09028452571.iix
deleted file mode 100644
index 918e0e5..0000000
--- a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.iix
+++ /dev/null
Binary files differ
diff --git a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.rix b/.bzr/repository/indices/21eed38863b95e047c05b09028452571.rix
deleted file mode 100644
index 1f84957..0000000
--- a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.rix
+++ /dev/null
Binary files differ
diff --git a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.six b/.bzr/repository/indices/21eed38863b95e047c05b09028452571.six
deleted file mode 100644
index c27d962..0000000
--- a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.six
+++ /dev/null
Binary files differ
diff --git a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.tix b/.bzr/repository/indices/21eed38863b95e047c05b09028452571.tix
deleted file mode 100644
index 41f2c69..0000000
--- a/.bzr/repository/indices/21eed38863b95e047c05b09028452571.tix
+++ /dev/null
Binary files differ
diff --git a/.bzr/repository/pack-names b/.bzr/repository/pack-names
deleted file mode 100644
index 72cabc8..0000000
--- a/.bzr/repository/pack-names
+++ /dev/null
@@ -1,6 +0,0 @@
-B+Tree Graph Index 2
-node_ref_lists=0
-key_elements=1
-len=1
-row_lengths=1
-xœ Ê«€0 ÀêNÑò{M*†BP†í©:sï÷ävç~UáÌS#ºÎ$óƒ0i„Aà\Š8,ÐÄÚKøÐXª+¯åõ[_… \ No newline at end of file
diff --git a/.bzr/repository/packs/21eed38863b95e047c05b09028452571.pack b/.bzr/repository/packs/21eed38863b95e047c05b09028452571.pack
deleted file mode 100644
index 16a9bd1..0000000
--- a/.bzr/repository/packs/21eed38863b95e047c05b09028452571.pack
+++ /dev/null
Binary files differ
diff --git a/.bzrignore b/.bzrignore
deleted file mode 100644
index f89141c..0000000
--- a/.bzrignore
+++ /dev/null
@@ -1,176 +0,0 @@
-00_header
-10_*
-20_linux_xen
-30_os-prober
-40_custom
-41_custom
-*.1
-*.8
-aclocal.m4
-ascii.bitmaps
-ascii.h
-autom4te.cache
-build_env.mk
-.bzrignore
-config.cache
-config.guess
-config.h
-config-util.h
-config-util.h.in
-config.log
-config.status
-config.sub
-configure
-DISTLIST
-docs/*.info
-docs/stamp-vti
-docs/version.texi
-*.elf
-example_grub_script_test
-example_scripted_test
-example_unit_test
-*.exec
-genkernsyms.sh
-gensymlist.sh
-gentrigtables
-grub-bin2h
-grub-bios-setup
-grub_cmd_echo
-grub_cmd_regexp
-grub-editenv
-grub-emu
-grub_emu_init.c
-grub_emu_init.h
-grub-fstest
-grub_fstest_init.c
-grub_fstest_init.h
-grub-install
-grub-kbdcomp
-grub-macho2img
-grub-menulst2cfg
-grub-mk*
-grub-mount
-grub-ofpathname
-grub-pe2elf
-grub-probe
-grub_probe_init.c
-grub_probe_init.h
-grub-reboot
-grub_script_blanklines
-grub_script_blockarg
-grub_script_break
-grub-script-check
-grub_script_check_init.c
-grub_script_check_init.h
-grub_script_comments
-grub_script_continue
-grub_script_dollar
-grub_script_echo1
-grub_script_echo_keywords
-grub_script_expansion
-grub_script_final_semicolon
-grub_script_for1
-grub_script_functions
-grub_script_if
-grub_script_not
-grub_script_return
-grub_script_setparams
-grub_script_shift
-grub_script_vars1
-grub_script_while1
-grub_script.tab.c
-grub_script.tab.h
-grub_script.yy.c
-grub_script.yy.h
-grub-set-default
-grub-setup
-grub_setup_init.c
-grub_setup_init.h
-grub-shell
-grub-shell-tester
-grub-sparc64-setup
-*.img
-*.image
-include/grub/cpu
-include/grub/machine
-install-sh
-lib/libgcrypt-grub
-libgrub_a_init.c
-*.lst
-*.marker
-Makefile
-*.mod
-mod-*.c
-missing
-partmap_test
-*.pf2
-*.pp
-po/*.mo
-po/grub.pot
-po/POTFILES
-po/stamp-po
-stamp-h
-stamp-h1
-stamp-h.in
-symlist.c
-symlist.h
-trigtables.c
-update-grub_lib
-unidata.c
-Makefile.in
-GPATH
-GRTAGS
-GSYMS
-GTAGS
-Makefile.tpl
-compile
-depcomp
-mdate-sh
-texinfo.tex
-grub-core/lib/libgcrypt-grub
-grub-core/lib/dtc-grub
-**/.deps
-**/.deps-util
-**/.deps-core
-**/.dirstamp
-Makefile.util.am
-contrib
-grub-core/Makefile.core.am
-grub-core/Makefile.gcry.def
-grub-core/Makefile.libfdt.def
-grub-core/contrib
-grub-core/gdb_grub
-grub-core/genmod.sh
-grub-core/gensyminfo.sh
-grub-core/gmodule.pl
-grub-core/modinfo.sh
-grub-core/*.module
-grub-core/*.pp
-util/bash-completion.d/grub
-grub-core/gnulib/alloca.h
-grub-core/gnulib/arg-nonnull.h
-grub-core/gnulib/c++defs.h
-grub-core/gnulib/charset.alias
-grub-core/gnulib/configmake.h
-grub-core/gnulib/getopt.h
-grub-core/gnulib/langinfo.h
-grub-core/gnulib/ref-add.sed
-grub-core/gnulib/ref-del.sed
-grub-core/gnulib/stdio.h
-grub-core/gnulib/stdlib.h
-grub-core/gnulib/string.h
-grub-core/gnulib/strings.h
-grub-core/gnulib/sys
-grub-core/gnulib/unistd.h
-grub-core/gnulib/warn-on-use.h
-grub-core/gnulib/wchar.h
-grub-core/gnulib/wctype.h
-grub-core/rs_decoder.S
-widthspec.bin
-widthspec.h
-docs/stamp-1
-docs/version-dev.texi
-Makefile.utilgcry.def
-po/*.po
-po/*.gmo
-po/LINGUAS
diff --git a/ChangeLog b/ChangeLog
index 9104a46..74ef434 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,675 @@
+2013-01-27 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * util/grub-install.in: change misleading comment about
+ device.map creation
+
+2013-01-27 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/normal/menu_text.c (grub_menu_init_page): Fix behaviour
+ when menu highlight color isn't set.
+
+2013-01-27 C. Masloch <pushbx@38.de>
+
+ Improve FreeDOS direct loading support compatibility.
+
+ * include/grub/i386/relocator.h (grub_relocator16_state):
+ New member ebp.
+ * grub-core/lib/i386/relocator.c (grub_relocator16_ebp): New extern
+ variable.
+ (grub_relocator16_boot): Handle %ebp.
+ * grub-core/lib/i386/relocator16.S: Likewise.
+ * grub-core/loader/i386/pc/freedos.c:
+ Load BPB to pass kernel which partition to load from.
+ Check that kernel file is not too large.
+ Set register dl to BIOS unit number as well.
+
+2013-01-22 Colin Watson <cjwatson@ubuntu.com>
+
+ * util/grub-reboot.in (usage): Document the need for
+ GRUB_DEFAULT=saved.
+ * util/grub-set-default.in (usage): Likewise.
+ Reported by: Brian Candler. Fixes Ubuntu bug #1102925.
+
+2013-01-21 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Include sys/types.h rather
+ than defining WORDS_BIGENDIAN manually.
+
+2013-01-21 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * include/grub/kernel.h (FOR_MODULES): Adjust to preserve alignment
+ invariants.
+
+2013-01-21 Colin Watson <cjwatson@ubuntu.com>
+
+ * grub-core/font/font.c (blit_comb: do_blit): Make static instead of
+ nested.
+ (blit_comb: add_device_width): Likewise.
+
+2013-01-21 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove nested functions from USB iterators.
+
+ * include/grub/usb.h (grub_usb_iterate_hook_t): New type.
+ (grub_usb_controller_iterate_hook_t): Likewise.
+ (grub_usb_iterate): Add hook_data argument.
+ (grub_usb_controller_iterate): Likewise.
+ (struct grub_usb_controller_dev.iterate): Likewise.
+
+ Update all implementations and callers.
+
+2013-01-21 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/normal/term.c (print_ucs4_terminal): Don't output right
+ margin when not needed.
+
+2013-01-21 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Make color variables global instead of it being per-terminal.
+
+2013-01-21 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/ls.c (grub_ls_print_devices): Add missing
+ asterisk.
+
+2013-01-21 Colin Watson <cjwatson@ubuntu.com>
+
+ Fix powerpc and sparc64 build failures caused by un-nesting memory
+ map iterators.
+
+2013-01-21 Colin Watson <cjwatson@ubuntu.com>
+
+ * grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate): Fix
+ parameter declarations.
+
+2013-01-21 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/lsmmap.c: Fix unused variable on emu.
+
+2013-01-21 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Improve spkmomdem reliability by adding a separator between bytes.
+
+2013-01-21 Colin Watson <cjwatson@ubuntu.com>
+
+ * grub-core/partmap/msdos.c (embed_signatures): Add the signature of
+ an Acer registration utility with several sightings in the wild.
+ Reported by: Rickard Westman. Fixes Ubuntu bug #987022.
+
+2013-01-21 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove nested functions from filesystem directory iterators.
+
+ * include/grub/fs.h (grub_fs_dir_hook_t): New type.
+ (struct grub_fs.dir): Add hook_data argument.
+
+ Update all implementations and callers.
+
+2013-01-21 Colin Watson <cjwatson@ubuntu.com>
+
+ * docs/grub.texi (Multi-boot manual config): Fix typo for
+ "recommended".
+
+2013-01-20 Leif Lindholm <leif.lindholm@arm.com>
+
+ * util/grub-mkimage.c (main): Postpone freeing arguments.output
+ until after its use in generate_image.
+
+2013-01-20 Colin Watson <cjwatson@ubuntu.com>
+
+ * grub-core/loader/i386/linux.c (grub_cmd_initrd): Don't add the
+ initrd size to addr_min, since the initrd will be allocated after
+ this address.
+
+2013-01-20 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * conf/Makefile.common: Fix autogen rules to pass definition
+ files on stdin; Makefile.util.am needs Makefile.utilgcry.def
+
+2013-01-20 Leif Lindholm <leif.lindholm@arm.com>
+
+ * include/grub/elf.h: Update ARM definitions based on binutils.
+
+2013-01-20 Aleš Nesrsta <starous@volny.cz>
+
+ Split long USB transfers into short ones.
+
+2013-01-20 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * docs/grub.texi (Simple configuration): Clarify GRUB_HIDDEN_TIMEOUT
+ is interrupted by ESC.
+
+2013-01-20 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * util/grub-script-check.c (main): Uniform the error message.
+
+2013-01-20 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove nested functions from ELF iterators.
+
+2013-01-20 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove nested functions from device iterators.
+
+ * include/grub/arc/arc.h (grub_arc_iterate_devs_hook_t): New type.
+ (grub_arc_iterate_devs): Add hook_data argument.
+ * include/grub/ata.h (grub_ata_dev_iterate_hook_t): New type.
+ (struct grub_ata_dev.iterate): Add hook_data argument.
+ * include/grub/device.h (grub_device_iterate_hook_t): New type.
+ (grub_device_iterate): Add hook_data argument.
+ * include/grub/disk.h (grub_disk_dev_iterate_hook_t): New type.
+ (struct grub_disk_dev.iterate): Add hook_data argument.
+ (grub_disk_dev_iterate): Likewise.
+ * include/grub/gpt_partition.h (grub_gpt_partition_map_iterate):
+ Likewise.
+ * include/grub/msdos_partition.h (grub_partition_msdos_iterate):
+ Likewise.
+ * include/grub/partition.h (grub_partition_iterate_hook_t): New
+ type.
+ (struct grub_partition_map.iterate): Add hook_data argument.
+ (grub_partition_iterate): Likewise.
+ * include/grub/scsi.h (grub_scsi_dev_iterate_hook_t): New type.
+ (struct grub_scsi_dev.iterate): Add hook_data argument.
+
+ Update all callers.
+
+2013-01-20 Colin Watson <cjwatson@ubuntu.com>
+
+ Fix typos for "developer" and "development".
+
+2013-01-18 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Add license header to spkmodem-recv.c.
+
+2013-01-17 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Rewrite spkmodem to use PIT for timing. Double the speed.
+
+2013-01-16 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Add new command pcidump.
+
+2013-01-16 Vladimir Serbinenko <phcoder@gmail.com>
+
+ New terminal outputs using serial: morse and spkmodem.
+
+2013-01-16 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Improve bidi handling in entry editor.
+
+2013-01-16 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/script/lexer.c (grub_script_lexer_init): Rename getline
+ argument to prevent name collision.
+
+2013-01-15 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove nested functions from script reading and parsing.
+
+ * grub-core/kern/parser.c (grub_parser_split_cmdline): Add
+ getline_data argument, passed to getline.
+ * grub-core/kern/rescue_parser.c (grub_rescue_parse_line): Add
+ getline_data argument, passed to grub_parser_split_cmdline.
+ * grub-core/script/lexer.c (grub_script_lexer_yywrap): Pass
+ lexerstate->getline_data to lexerstate->getline.
+ (grub_script_lexer_init): Add getline_data argument, saved in
+ lexerstate->getline_data.
+ * grub-core/script/main.c (grub_normal_parse_line): Add getline_data
+ argument, passed to grub_script_parse.
+ * grub-core/script/script.c (grub_script_parse): Add getline_data
+ argument, passed to grub_script_lexer_init.
+ * include/grub/parser.h (grub_parser_split_cmdline): Update
+ prototype. Update all callers to pass appropriate getline data.
+ (struct grub_parser.parse_line): Likewise.
+ (grub_rescue_parse_line): Likewise.
+ * include/grub/reader.h (grub_reader_getline_t): Add void *
+ argument.
+ * include/grub/script_sh.h (struct grub_lexer_param): Add
+ getline_data member.
+ (grub_script_parse): Update prototype. Update all callers to pass
+ appropriate getline data.
+ (grub_script_lexer_init): Likewise.
+ (grub_normal_parse_line): Likewise.
+
+ * grub-core/commands/legacycfg.c (legacy_file_getline): Add unused
+ data argument.
+ * grub-core/kern/parser.c (grub_parser_execute: getline): Make
+ static instead of nested. Rename to ...
+ (grub_parser_execute_getline): ... this.
+ * grub-core/kern/rescue_reader.c (grub_rescue_read_line): Add unused
+ data argument.
+ * grub-core/normal/main.c (read_config_file: getline): Make static
+ instead of nested. Rename to ...
+ (read_config_file_getline): ... this.
+ (grub_normal_read_line): Add unused data argument.
+ * grub-core/script/execute.c (grub_script_execute_sourcecode:
+ getline): Make static instead of nested. Rename to ...
+ (grub_script_execute_sourcecode_getline): ... this.
+ * util/grub-script-check.c (main: get_config_line): Make static
+ instead of nested.
+
+2013-01-15 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove nested functions from memory map iterators.
+
+ * grub-core/efiemu/mm.c (grub_efiemu_mmap_iterate): Add hook_data
+ argument, passed to hook.
+ * grub-core/kern/i386/coreboot/mmap.c
+ (grub_linuxbios_table_iterate): Likewise.
+ (grub_machine_mmap_iterate: iterate_linuxbios_table): Make static
+ instead of nested.
+ (grub_machine_mmap_iterate): Add hook_data argument.
+ * grub-core/kern/i386/multiboot_mmap.c (grub_machine_mmap_iterate):
+ Add hook_data argument, passed to hook.
+ * grub-core/kern/i386/pc/mmap.c (grub_machine_mmap_iterate):
+ Likewise.
+ * grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_iterate):
+ Likewise.
+ * grub-core/kern/ieee1275/mmap.c (grub_machine_mmap_iterate):
+ Likewise.
+ * grub-core/kern/mips/arc/init.c (grub_machine_mmap_iterate):
+ Likewise.
+ * grub-core/kern/mips/loongson/init.c (grub_machine_mmap_iterate):
+ Likewise.
+ * grub-core/kern/mips/qemu_mips/init.c (grub_machine_mmap_iterate):
+ Likewise.
+ * grub-core/mmap/efi/mmap.c (grub_efi_mmap_iterate): Likewise.
+ (grub_machine_mmap_iterate): Likewise.
+ * grub-core/mmap/mmap.c (grub_mmap_iterate): Likewise.
+ * include/grub/efiemu/efiemu.h (grub_efiemu_mmap_iterate): Update
+ prototype.
+ * include/grub/memory.h (grub_memory_hook_t): Add data argument.
+ Remove NESTED_FUNC_ATTR from here and from all users.
+ (grub_mmap_iterate): Update prototype.
+ (grub_efi_mmap_iterate): Update prototype. Update all callers to
+ pass appropriate hook data.
+ (grub_machine_mmap_iterate): Likewise.
+
+ * grub-core/commands/acpi.c (grub_acpi_create_ebda: find_hook): Make
+ static instead of nested.
+ * grub-core/commands/lsmmap.c (grub_cmd_lsmmap: hook): Likewise.
+ Rename to ...
+ (lsmmap_hook): ... this.
+ * grub-core/efiemu/mm.c (grub_efiemu_mmap_init: bounds_hook):
+ Likewise.
+ (grub_efiemu_mmap_fill: fill_hook): Likewise.
+ * grub-core/kern/i386/coreboot/init.c (grub_machine_init:
+ heap_init): Likewise.
+ * grub-core/kern/i386/pc/init.c (grub_machine_init: hook): Likewise.
+ Rename to ...
+ (mmap_iterate_hook): ... this.
+ * grub-core/kern/ieee1275/init.c (grub_claim_heap: heap_init):
+ Likewise.
+ * grub-core/lib/ieee1275/relocator.c
+ (grub_relocator_firmware_get_max_events: count): Likewise.
+ (grub_relocator_firmware_fill_events: fill): Likewise. Rename
+ to ...
+ (grub_relocator_firmware_fill_events_iter): ... this.
+ * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align:
+ hook): Likewise. Rename to ...
+ (grub_relocator_alloc_chunk_align_iter): ... this.
+ * grub-core/loader/i386/bsd.c (generate_e820_mmap: hook): Likewise.
+ Rename to ...
+ (generate_e820_mmap_iter): ... this.
+ * grub-core/loader/i386/linux.c (find_mmap_size: hook): Likewise.
+ Rename to ...
+ (count_hook): ... this.
+ (grub_linux_boot: hook): Likewise. Rename to ...
+ (grub_linux_boot_mmap_find): ... this.
+ (grub_linux_boot: hook_fill): Likewise. Rename to ...
+ (grub_linux_boot_mmap_fill): ... this.
+ * grub-core/loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap:
+ hook): Likewise. Rename to ...
+ (grub_fill_multiboot_mmap_iter): ... this.
+ * grub-core/loader/multiboot.c (grub_get_multiboot_mmap_count:
+ hook): Likewise. Rename to ...
+ (count_hook): ... this.
+ * grub-core/loader/multiboot_mbi2.c (grub_fill_multiboot_mmap:
+ hook): Likewise. Rename to ...
+ (grub_fill_multiboot_mmap_iter): ... this.
+ * grub-core/loader/powerpc/ieee1275/linux.c
+ (grub_linux_claimmap_iterate: alloc_mem): Likewise.
+ * grub-core/loader/sparc64/ieee1275/linux.c (alloc_phys: choose):
+ Likewise. Rename to ...
+ (alloc_phys_choose): ... this.
+ (determine_phys_base: get_physbase): Likewise.
+ * grub-core/mmap/i386/mmap.c (grub_mmap_malign_and_register:
+ find_hook): Likewise.
+ * grub-core/mmap/i386/pc/mmap.c (preboot: fill_hook): Likewise.
+ (malloc_hook: count_hook): Likewise.
+ * grub-core/mmap/i386/uppermem.c (grub_mmap_get_lower: hook):
+ Likewise. Rename to ...
+ (lower_hook): ... this.
+ (grub_mmap_get_upper: hook): Likewise. Rename to ...
+ (upper_hook): ... this.
+ (grub_mmap_get_post64: hook): Likewise. Rename to ...
+ (post64_hook): ... this.
+ * grub-core/mmap/mips/uppermem.c (grub_mmap_get_lower: hook):
+ Likewise. Rename to ...
+ (lower_hook): ... this.
+ (grub_mmap_get_upper: hook): Likewise. Rename to ...
+ (upper_hook): ... this.
+ * grub-core/mmap/mmap.c (grub_mmap_iterate: count_hook): Likewise.
+ (grub_mmap_iterate: fill_hook): Likewise.
+ (fill_mask): Pass addr and mask within a single struct.
+ (grub_cmd_badram: hook): Make static instead of nested. Rename
+ to ...
+ (badram_iter): ... this.
+ (grub_cmd_cutmem: hook): Likewise. Rename to ...
+ (cutmem_iter): ... this.
+
+2013-01-13 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/kern/emu/hostdisk.c (read_device_map): Explicitly
+ delimit path in strings using quotes.
+ * util/getroot.c (grub_guess_root_devices): Likewise.
+ (grub_make_system_path_relative_to_its_root): Likewise.
+ * util/grub-probe.c (probe): Likewise.
+ * util/ieee1275/ofpath.c (find_obppath): Likewise.
+ (xrealpath): Likewise.
+
+2013-01-13 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Fix compilation with older compilers.
+
+ * grub-core/Makefile.core.def (mpi): Add mpi-inline.c.
+ * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Remove redundant
+ declarations.
+ * grub-core/lib/posix_wrap/string.h: Include sys/types.h.
+ * grub-core/lib/posix_wrap/sys/types.h: Add common types.
+ * grub-core/lib/xzembed/xz_dec_lzma2.c (dict_put): Replace byte
+ identifier with b.
+ * grub-core/lib/xzembed/xz_dec_stream.c (dec_vli): Likewise.
+ * include/grub/crypto.h: Add type defines.
+ * util/import_gcrypth.sed: Remove duplicate type defines.
+
+2013-01-13 Vladimir Serbinenko <phcoder@gmail.com>
+
+ New command list_trusted.
+
+ * grub-core/commands/verify.c (grub_cmd_list): New function.
+
+2013-01-13 Colin Watson <cjwatson@ubuntu.com>
+
+ * util/grub-mkimage.c (generate_image): Fix "size of public key"
+ info message.
+
+2013-01-13 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove nested functions from PCI iterators.
+
+ * grub-core/bus/pci.c (grub_pci_iterate): Add hook_data argument,
+ passed to hook. Update all callers to pass appropriate hook data.
+ * grub-core/bus/emu/pci.c (grub_pci_iterate): Likewise.
+ * include/grub/pci.h (grub_pci_iteratefunc_t): Add data argument.
+ Remove NESTED_FUNC_ATTR from here and from all users.
+ (grub_pci_iterate): Update prototype.
+ * grub-core/bus/cs5536.c (grub_cs5536_find: hook): Make static
+ instead of nested. Rename to ...
+ (grub_cs5536_find_iter): ... this.
+ * grub-core/kern/efi/mm.c (stop_broadcom: find_card): Likewise.
+ * grub-core/kern/mips/loongson/init.c (init_pci: set_card):
+ Likewise.
+ * grub-core/kern/vga_init.c (grub_qemu_init_cirrus: find_card):
+ Likewise.
+ * grub-core/video/bochs.c (grub_video_bochs_setup: find_card):
+ Likewise.
+ * grub-core/video/cirrus.c (grub_video_cirrus_setup: find_card):
+ Likewise.
+ * grub-core/video/efi_uga.c (find_framebuf: find_card): Likewise.
+ * grub-core/video/radeon_fuloong2e.c
+ (grub_video_radeon_fuloong2e_setup: find_card): Likewise.
+ * grub-core/video/sis315pro.c (grub_video_sis315pro_setup:
+ find_card): Likewise.
+ * grub-core/video/sm712.c (grub_video_sm712_setup: find_card):
+ Likewise.
+
+2013-01-12 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/verify.c: Mark messages for translating.
+
+2013-01-12 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/lib/libgcrypt_wrap/mem.c (gcry_x*alloc): Make out of memory
+ fatal.
+
+2013-01-12 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/lib/libgcrypt_wrap/mem.c (_gcry_log_bug): Make gcrypt bugs
+ fatal.
+
+2013-01-12 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * autogen.sh: Do not try to delete nonexistant files.
+ * util/import_gcrypth.sed: Add some missing header removals.
+
+2013-01-12 Colin Watson <cjwatson@ubuntu.com>
+
+ Clean up dangling references to grub-setup.
+ Fixes Ubuntu bug #1082045.
+
+ * docs/grub.texi (Images): Refer generally to grub-install rather
+ than directly to grub-setup.
+ (Installing GRUB using grub-install): Remove direct reference to
+ grub-setup.
+ (Device map) Likewise.
+ (Invoking grub-install): Likewise.
+ * docs/man/grub-install.h2m (SEE ALSO): Likewise.
+ * docs/man/grub-mkimage.h2m (SEE ALSO): Likewise.
+ * util/grub-install.in (usage): Likewise.
+
+ * util/bash-completion.d/grub-completion.bash.in (_grub_setup):
+ Apply to grub-bios-setup and grub-sparc64-setup rather than to
+ grub-setup.
+ * configure.ac: Remove grub_setup output variable.
+
+ * docs/man/grub-bios-setup.h2m (NAME): Change name from grub-setup
+ to grub-bios-setup.
+ * docs/man/grub-sparc64-setup.h2m (NAME): Change name from
+ grub-setup to grub-sparc64-setup.
+
+2013-01-11 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Import gcrypt public-key cryptography and implement signature checking.
+
+2013-01-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/ntfs.c: Ue more appropriate types.
+ * grub-core/fs/ntfscomp.c: Likewise.
+ * include/grub/ntfs.h: Likewise.
+
+2013-01-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Support Apple FAT binaries on non-Apple platforms.
+
+ * include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define.
+ * include/grub/i386/macho.h (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT):
+ Likewise.
+ * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Parse
+ Apple FAT binaries.
+
+2013-01-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/kern/disk.c (grub_disk_write): Fix sector number on 4K
+ sector devices.
+
+2013-01-07 Colin Watson <cjwatson@ubuntu.com>
+
+ * grub-core/io/bufio.c (grub_bufio_open): Use grub_zalloc instead of
+ explicitly zeroing elements.
+ * grub-core/io/gzio.c (grub_gzio_open): Likewise.
+ * grub-core/io/lzopio.c (grub_lzopio_open): Remove explicit zeroing
+ of elements in a structure already allocated using grub_zalloc.
+ * grub-core/io/xzio.c (grub_xzio_open): Likewise.
+
+2013-01-07 Colin Watson <cjwatson@ubuntu.com>
+
+ * docs/grub.texi (grub_cpu): New subsection.
+ (grub_platform): Likewise.
+
+2013-01-07 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/minix.c (grub_minix_read_file): Simplify arithmetics.
+
+2013-01-05 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/ext2.c (grub_ext2_read_block): Use shifts rather than
+ divisions.
+
+2013-01-05 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/ntfs.c: Eliminate useless divisions in favor of shifts.
+ * grub-core/fs/ntfscomp.c: Likewise.
+ * include/grub/ntfs.h (grub_ntfs_data): Replace spc with log_spc.
+ (grub_ntfs_comp): Likewise.
+
+2013-01-05 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/nilfs2.c (-grub_nilfs2_palloc_groups_per_desc_block):
+ Rename to ...
+ (grub_nilfs2_palloc_log_groups_per_desc_block): ... this. Return log
+ of groups_per_block. All users updated.
+
+2013-01-05 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/disk/diskfilter.c (grub_diskfilter_write): Call
+ grub_error properly.
+ * grub-core/disk/ieee1275/nand.c (grub_nand_write): Likewise.
+ * grub-core/disk/loopback.c (grub_loopback_write): Likewise.
+
+2013-01-03 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * util/grub.d/10_kfreebsd.in: Correct the patch to zpool.cache as it's
+ always in /boot/zfs.
+ Reported by: Yuta Satoh.
+
+2013-01-03 Yuta Satoh <nigoro>
+
+ * util/grub.d/10_kfreebsd.in: Fix improper references to grub-probe by
+ ${grub_probe}
+
+2013-01-03 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * configure.ac: Extend -Wno-trampolines to host.
+
+2013-01-03 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/iso9660.c (grub_iso9660_susp_iterate): Avoid hang if
+ entry->len = 0.
+
+2013-01-03 Colin Watson <cjwatson@ubuntu.com>
+
+ * docs/grub.texi (Invoking grub-mkrelpath): New section.
+ (Invoking grub-script-check): Likewise.
+
+2013-01-03 Colin Watson <cjwatson@ubuntu.com>
+
+ * docs/grub.texi (Invoking grub-mount): New section.
+ Reported by: Filipus Klutiero. Fixes Debian bug #666427.
+
+2013-01-02 Colin Watson <cjwatson@ubuntu.com>
+
+ * grub-core/tests/lib/test.c (grub_test_run): Return non-zero on
+ test failures, so that a failing unit test correctly causes 'make
+ check' to fail.
+
+2013-01-02 Colin Watson <cjwatson@ubuntu.com>
+
+ Fix failing printf test.
+
+ * grub-core/kern/misc.c (grub_vsnprintf_real): Parse '-', '.', and
+ '$' in the correct order when collecting type information.
+
+2013-01-02 Colin Watson <cjwatson@ubuntu.com>
+
+ * docs/grub.texi (configfile): Explain environment variable
+ handling.
+ (source): New section.
+ Reported by: Arbiel Perlacremaz. Fixes Savannah bug #35564.
+
+2012-12-31 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove several trivially-unnecessary uses of nested functions.
+
+ * grub-core/commands/i386/pc/sendkey.c
+ (grub_cmd_sendkey: find_key_code, find_ascii_code): Make static
+ instead of nested.
+ * grub-core/commands/legacycfg.c (legacy_file: getline): Likewise.
+ Rename to ...
+ (legacy_file_getline): ... this.
+ * grub-core/commands/loadenv.c (grub_cmd_load_env: set_var):
+ Likewise.
+ * grub-core/kern/corecmd.c (grub_core_cmd_set: print_env): Likewise.
+ * grub-core/kern/fs.c (grub_fs_probe: dummy_func): Likewise. Rename
+ to ...
+ (probe_dummy_iter): ... this.
+ * grub-core/kern/i386/coreboot/mmap.c
+ (grub_linuxbios_table_iterate: check_signature): Likewise.
+ * grub-core/kern/parser.c (grub_parser_split_cmdline:
+ check_varstate): Likewise. Mark inline.
+ * grub-core/lib/arg.c (find_short: fnd_short): Likewise. Pass
+ an additional parameter.
+ (find_long: fnd_long): Likewise. Pass two additional parameters.
+ * grub-core/lib/crc.c (init_crc32c_table: reflect): Likewise.
+ * grub-core/lib/crc64.c (init_crc64_table: reflect): Likewise.
+ * grub-core/lib/ieee1275/cmos.c (grub_cmos_find_port: hook):
+ Likewise. Rename to ...
+ (grub_cmos_find_port_iter): ... this.
+ * grub-core/lib/ieee1275/datetime.c (find_rtc: hook): Likewise.
+ Rename to ...
+ (find_rtc_iter): ... this.
+
+ * grub-core/normal/menu_entry.c (run): Fold nested editor_getsource
+ function directly into the function body, since it is only called
+ once.
+
+2012-12-30 Colin Watson <cjwatson@ubuntu.com>
+
+ * grub-core/bus/usb/ehci.c (grub_ehci_pci_iter): Remove incorrect
+ __attribute__ ((unused)).
+ * grub-core/video/bochs.c (find_card): Likewise.
+ * grub-core/video/cirrus.c (find_card): Likewise.
+ * grub-core/video/radeon_fuloong2e.c (find_card): Likewise.
+ * grub-core/video/sis315pro.c (find_card): Likewise.
+ * grub-core/video/sm712.c (find_card): Likewise.
+
+2012-12-28 Colin Watson <cjwatson@ubuntu.com>
+
+ * util/grub-mkconfig.in: Accept GRUB_TERMINAL_OUTPUT=vga_text.
+ Fixes Savannah bug #37821.
+
+2012-12-28 Colin Watson <cjwatson@ubuntu.com>
+
+ Apply program name transformations at build-time rather than at
+ run-time. Fixes Debian bug #696465.
+
+ * acinclude.m4 (grub_TRANSFORM): New macro.
+ * configure.ac: Create output variables with transformed names for
+ most programs.
+ * util/bash-completion.d/grub-completion.bash.in: Use
+ pre-transformed variables for program names.
+ * util/grub-install.in: Likewise.
+ * util/grub-kbdcomp.in: Likewise.
+ * util/grub-mkconfig.in: Likewise.
+ * util/grub-mkconfig_lib.in: Likewise.
+ * util/grub-mknetdir.in: Likewise.
+ * util/grub-mkrescue.in: Likewise.
+ * util/grub-mkstandalone.in: Likewise.
+ * util/grub-reboot.in: Likewise.
+ * util/grub-set-default.in: Likewise.
+ * util/powerpc/ieee1275/grub-mkrescue.in: Likewise.
+ * tests/util/grub-shell-tester.in: Remove unused assignment.
+ * tests/util/grub-shell.in: Likewise.
+ * util/grub.d/00_header.in: Likewise.
+
+2012-12-28 Colin Watson <cjwatson@ubuntu.com>
+
+ Backport gnulib fixes for C11. Fixes Savannah bug #37738.
+
+ * grub-core/gnulib/stdio.in.h (gets): Warn on use only if
+ HAVE_RAW_DECL_GETS.
+ * m4/stdio_h.m4 (gl_STDIO_H): Check for gets.
+
2012-12-11 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub.d/20_linux_xen.in: Addmissing assignment to machine.
diff --git a/Makefile.util.def b/Makefile.util.def
index 6a123ff..262f9c0 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -213,8 +213,6 @@ program = {
ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
- cflags = '$(CFLAGS_GCRY)';
- cppflags = '$(CPPFLAGS_GCRY)';
};
program = {
@@ -245,9 +243,6 @@ program = {
common = grub-core/kern/emu/hostfs.c;
common = grub-core/disk/host.c;
- cflags = '$(CFLAGS_GCRY)';
- cppflags = '$(CPPFLAGS_GCRY)';
-
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
diff --git a/acinclude.m4 b/acinclude.m4
index 0eb2e2a..49a1a75 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -452,3 +452,9 @@ else
AC_MSG_RESULT([no])
[fi]
])
+
+dnl Create an output variable with the transformed name of a GRUB utility
+dnl program.
+AC_DEFUN([grub_TRANSFORM],[dnl
+AC_SUBST(AS_TR_SH([$1]), [`AS_ECHO([$1]) | sed "$program_transform_name"`])dnl
+])
diff --git a/autogen.sh b/autogen.sh
index 6e4d8ca..6df462e 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -13,6 +13,22 @@ python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt
echo "Importing libgcrypt..."
python util/import_gcry.py grub-core/lib/libgcrypt/ grub-core
+sed -n -f util/import_gcrypth.sed < grub-core/lib/libgcrypt/src/gcrypt.h.in > include/grub/gcrypt/gcrypt.h
+if [ -f include/grub/gcrypt/g10lib.h ]; then
+ rm include/grub/gcrypt/g10lib.h
+fi
+if [ -d grub-core/lib/libgcrypt-grub/mpi/generic ]; then
+ rm -rf grub-core/lib/libgcrypt-grub/mpi/generic
+fi
+ln -s ../../../grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10lib.h
+cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic
+
+for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do
+ if [ -f grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then
+ rm grub-core/lib/libgcrypt-grub/mpi/"$x"
+ fi
+ ln -s generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x"
+done
echo "Importing libfdt..."
python util/import_libfdt.py grub-core/lib/dtc/ grub-core
diff --git a/conf/Makefile.common b/conf/Makefile.common
index f03701a..a9c0fd0 100644
--- a/conf/Makefile.common
+++ b/conf/Makefile.common
@@ -40,7 +40,7 @@ endif
if COND_arm
# Image entry point always in ARM (A32) state - ensure proper functionality if
# the rest is built for the Thumb (T32) state.
- CFLAGS_PLATFORM += -mthumb-interwork -mno-unaligned-access
+ CFLAGS_PLATFORM += -mthumb-interwork -mno-unaligned-access -mlong-calls
CCASFLAGS_PLATFORM = -Wa,-mimplicit-it=thumb
endif
@@ -53,6 +53,8 @@ CPPFLAGS_DEFAULT += -I$(top_builddir)
CPPFLAGS_DEFAULT += -I$(top_srcdir)
CPPFLAGS_DEFAULT += -I$(top_srcdir)/include
CPPFLAGS_DEFAULT += -I$(top_builddir)/include
+CPPFLAGS_DEFAULT += -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/include
+CPPFLAGS_DEFAULT += -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/src/
CCASFLAGS_DEFAULT = -DASM_FILE=1
LDADD_KERNEL =
@@ -114,9 +116,6 @@ grubconfdir = $(sysconfdir)/grub.d
platformdir = $(pkglibdir)/$(target_cpu)-$(platform)
starfielddir = $(pkgdatadir)/themes/starfield
-CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers
-CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap
-
CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition -Wno-unsafe-loop-optimizations
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib
@@ -125,6 +124,9 @@ CPPFLAGS_LIBFDT = -I$(top_srcdir)/grub-core/lib/dtc-grub/libfdt
CFLAGS_POSIX = -fno-builtin
CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap
+CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers $(CFLAGS_POSIX)
+CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt
+
CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime
# List file macros for recognizing /interesting/ modules
@@ -181,12 +183,12 @@ $(top_srcdir)/Makefile.tpl: $(top_srcdir)/gentpl.py
mv $@.new $@
.PRECIOUS: $(top_srcdir)/Makefile.util.am
-$(top_srcdir)/Makefile.util.am: $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.tpl
- autogen -T $(top_srcdir)/Makefile.tpl $< | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1)
+$(top_srcdir)/Makefile.util.am: $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def $(top_srcdir)/Makefile.tpl
+ cat $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def | autogen -T $(top_srcdir)/Makefile.tpl | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1)
mv $@.new $@
.PRECIOUS: $(top_srcdir)/grub-core/Makefile.core.am
$(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def $(top_srcdir)/Makefile.tpl
if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./autogen.sh manually." >&2; exit 1; fi
- autogen -T $(top_srcdir)/Makefile.tpl $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1)
+ cat $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def | autogen -T $(top_srcdir)/Makefile.tpl | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1)
mv $@.new $@
diff --git a/configure.ac b/configure.ac
index 4b5d92d..45a3289 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,21 @@ AC_CONFIG_HEADER([config-util.h])
# Program name transformations
AC_ARG_PROGRAM
+grub_TRANSFORM([grub-bios-setup])
+grub_TRANSFORM([grub-editenv])
+grub_TRANSFORM([grub-install])
+grub_TRANSFORM([grub-mkconfig])
+grub_TRANSFORM([grub-mkfont])
+grub_TRANSFORM([grub-mkimage])
+grub_TRANSFORM([grub-mklayout])
+grub_TRANSFORM([grub-mkpasswd-pbkdf2])
+grub_TRANSFORM([grub-mkrelpath])
+grub_TRANSFORM([grub-mkrescue])
+grub_TRANSFORM([grub-probe])
+grub_TRANSFORM([grub-reboot])
+grub_TRANSFORM([grub-script-check])
+grub_TRANSFORM([grub-set-default])
+grub_TRANSFORM([grub-sparc64-setup])
# Optimization flag. Allow user to override.
if test "x$TARGET_CFLAGS" = x; then
@@ -349,6 +364,23 @@ AC_CHECK_HEADER([util.h], [
])
AC_SUBST([LIBUTIL])
+AC_CACHE_CHECK([whether -Wno-trampolines work], [grub_cv_host_cc_wnotrampolines], [
+ SAVED_CFLAGS="$CFLAGS"
+ # Test for -Wtrampolines rather than -Wno-trampolines to reduce confusion
+ # in the event of later failures (since -Wno-* is always accepted, but
+ # produces a diagnostic if something else is wrong).
+ CFLAGS="$HOST_CFLAGS -Wtrampolines"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>
+int va_arg_func (int fixed, va_list args);]], [[]])],
+ [grub_cv_host_cc_wnotrampolines=yes],
+ [grub_cv_host_cc_wnotrampolines=no])
+ CFLAGS="$SAVED_CFLAGS"
+])
+
+if test x"$grub_host_cv_cc_wnotrampolines" = xyes ; then
+ HOST_CFLAGS="$HOST_CFLAGS -Wno-trampolines"
+fi
+
#
# Check for host and build compilers.
#
diff --git a/docs/grub.texi b/docs/grub.texi
index 39d9614..21ae47f 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -20,7 +20,7 @@
This manual is for GNU GRUB (version @value{VERSION},
@value{UPDATED}).
-Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010,2011,2012 Free Software Foundation, Inc.
+Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -36,8 +36,11 @@ Invariant Sections.
* grub-install: (grub)Invoking grub-install. Install GRUB on your drive
* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration
* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2.
+* grub-mkrelpath: (grub)Invoking grub-mkrelpath.
* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image
+* grub-mount: (grub)Invoking grub-mount. Mount a file system using GRUB
* grub-probe: (grub)Invoking grub-probe. Probe device information
+* grub-script-check: (grub)Invoking grub-script-check.
@end direntry
@setchapternewpage odd
@@ -100,8 +103,11 @@ This edition documents version @value{VERSION}.
* Invoking grub-mkconfig:: Generate a GRUB configuration file
* Invoking grub-mkpasswd-pbkdf2::
Generate GRUB password hashes
+* Invoking grub-mkrelpath:: Make system path relative to its root
* Invoking grub-mkrescue:: Make a GRUB rescue image
+* Invoking grub-mount:: Mount a file system using GRUB
* Invoking grub-probe:: Probe device information for GRUB
+* Invoking grub-script-check:: Check GRUB script file for syntax errors
* Obtaining and Building GRUB:: How to obtain and build GRUB
* Reporting bugs:: Where you should send a bug report
* Future:: Some future plans on GRUB
@@ -616,11 +622,11 @@ This install doesn't conflict with standard install as long as they are in
separate directories.
Note that @command{grub-install} is actually just a shell script and the
-real task is done by @command{grub-mkimage} and @command{grub-setup}.
-Therefore, you may run those commands directly to install GRUB, without
-using @command{grub-install}. Don't do that, however, unless you are very
-familiar with the internals of GRUB. Installing a boot loader on a running
-OS may be extremely dangerous.
+real task is done by other tools such as @command{grub-mkimage}. Therefore,
+you may run those commands directly to install GRUB, without using
+@command{grub-install}. Don't do that, however, unless you are very familiar
+with the internals of GRUB. Installing a boot loader on a running OS may be
+extremely dangerous.
@node Making a GRUB bootable CD-ROM
@section Making a GRUB bootable CD-ROM
@@ -682,8 +688,8 @@ storage devices.
@section The map between BIOS drives and OS devices
If the device map file exists, the GRUB utilities (@command{grub-probe},
-@command{grub-setup}, etc.) read it to map BIOS drives to OS devices. This
-file consists of lines like this:
+etc.) read it to map BIOS drives to OS devices. This file consists of lines
+like this:
@example
(@var{device}) @var{file}
@@ -1195,11 +1201,12 @@ immediately without displaying the menu, or to @samp{-1} to wait
indefinitely.
@item GRUB_HIDDEN_TIMEOUT
-Wait this many seconds for a key to be pressed before displaying the menu.
-If no key is pressed during that time, display the menu for the number of
+Wait this many seconds for @key{ESC} to be pressed before displaying the menu.
+If no @key{ESC} is pressed during that time, display the menu for the number of
seconds specified in GRUB_TIMEOUT before booting the default entry. We expect
that most people who use GRUB_HIDDEN_TIMEOUT will want to have GRUB_TIMEOUT set
-to @samp{0} so that the menu is not displayed at all unless a key is pressed.
+to @samp{0} so that the menu is not displayed at all unless @key{ESC} is
+pressed.
Unset by default.
@item GRUB_HIDDEN_TIMEOUT_QUIET
@@ -1223,9 +1230,9 @@ Select the terminal input device. You may select multiple devices here,
separated by spaces.
Valid terminal input names depend on the platform, but may include
-@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal),
-@samp{ofconsole} (Open Firmware console), @samp{at_keyboard} (PC AT
-keyboard, mainly useful with Coreboot), or @samp{usb_keyboard} (USB keyboard
+@samp{console} (native platform console), @samp{serial} (serial terminal),
+@samp{serial_<port>} (serial terminal with explicit port selection),
+@samp{at_keyboard} (PC AT keyboard), or @samp{usb_keyboard} (USB keyboard
using the HID Boot Protocol, for cases where the firmware does not handle
this).
@@ -1236,9 +1243,21 @@ Select the terminal output device. You may select multiple devices here,
separated by spaces.
Valid terminal output names depend on the platform, but may include
-@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal),
-@samp{gfxterm} (graphics-mode output), @samp{ofconsole} (Open Firmware
-console), or @samp{vga_text} (VGA text output, mainly useful with Coreboot).
+@samp{console} (native platform console), @samp{serial} (serial terminal),
+@samp{serial_<port>} (serial terminal with explicit port selection),
+@samp{gfxterm} (graphics-mode output), @samp{vga_text} (VGA text output),
+@samp{mda_text} (MDA text output), @samp{morse} (Morse-coding using system
+beeper) or @samp{spkmodem} (simple data protocol using system speaker).
+
+@samp{spkmodem} is useful when no serial port is available. Connect the output
+of sending system (where GRUB is running) to line-in of receiving system
+(usually developer machine).
+On receiving system compile @samp{spkmodem-recv} from
+@samp{util/spkmodem-recv.c} and run:
+
+@example
+parecord --channels=1 --rate=48000 --format=s16le | ./spkmodem-recv
+@end example
The default is to use the platform's native terminal output.
@@ -1638,7 +1657,7 @@ menuentry "Debian sid installer" @{
Notes:
@itemize
-@item Argument to search after --label is FS LABEL. You can also use UUIDs with --fs-uuid UUID instead of --label LABEL. You could also use direct @code{root=hd0,msdosX} but this is not recommened due to device name instability.
+@item Argument to search after --label is FS LABEL. You can also use UUIDs with --fs-uuid UUID instead of --label LABEL. You could also use direct @code{root=hd0,msdosX} but this is not recommended due to device name instability.
@end itemize
@node Embedded configuration
@@ -2277,8 +2296,8 @@ bytes.
The sole function of @file{boot.img} is to read the first sector of the core
image from a local disk and jump to it. Because of the size restriction,
@file{boot.img} cannot understand any file system structure, so
-@command{grub-setup} hardcodes the location of the first sector of the core
-image into @file{boot.img} when installing GRUB.
+@command{grub-install} hardcodes the location of the first sector of the
+core image into @file{boot.img} when installing GRUB.
@item diskboot.img
This image is used as the first sector of the core image when booting from a
@@ -2668,6 +2687,8 @@ These variables have special meaning to GRUB.
* gfxmode::
* gfxpayload::
* gfxterm_font::
+* grub_cpu::
+* grub_platform::
* icondir::
* lang::
* locale_dir::
@@ -2755,6 +2776,33 @@ those colors. Each color must be a name from the following list:
The default is @samp{white/black}.
+The color support support varies from terminal to terminal.
+
+@samp{morse} has no color support at all.
+
+@samp{mda_text} color support is limited to highlighting by
+black/white reversal.
+
+@samp{console} on ARC and IEEE1275, @samp{serial_*} and
+@samp{spkmodem} are governed by terminfo and support
+only 8 colors if in modes @samp{vt100-color}, @samp{arc}
+(default for console on ARC), @samp{ieee1275} (default
+for console on IEEE1275). When in mode @samp{vt100}
+then the color support is limited to highlighting by black/white
+reversal. When in mode @samp{dumb} there is no color support.
+
+@samp{console} on EMU supports 8 colors.
+
+When console supports no colors this setting is ignored.
+When console supports 8 colors, then the colors from the
+second half of the previous list are mapped to the
+matching colors of first half.
+
+@samp{console} on EFI and BIOS and @samp{vga_text} support all 16 colors.
+
+@samp{gfxterm} supports all 16 colors and would be theoretically extendable
+to support whole rgb24 palette but currently there is no compelling reason
+to go beyond the current 16 colors.
@node debug
@subsection debug
@@ -2851,6 +2899,20 @@ If this variable is set, it names a font to use for text on the
available font.
+@node grub_cpu
+@subsection grub_cpu
+
+In normal mode (@pxref{normal}), GRUB sets the @samp{grub_cpu} variable to
+the CPU type for which GRUB was built (e.g. @samp{i386} or @samp{powerpc}).
+
+
+@node grub_platform
+@subsection grub_platform
+
+In normal mode (@pxref{normal}), GRUB sets the @samp{grub_platform} variable
+to the platform for which GRUB was built (e.g. @samp{pc} or @samp{efi}).
+
+
@node icondir
@subsection icondir
@@ -3272,6 +3334,7 @@ you forget a command, you can run the command @command{help}
* cpuid:: Check for CPU features
* crc:: Calculate CRC32 checksums
* date:: Display or set current date and time
+* devicetree:: Load a Flattened Device Tree
* drivemap:: Map a drive to another
* echo:: Display a line of text
* export:: Export an environment variable
@@ -3303,6 +3366,7 @@ you forget a command, you can run the command @command{help}
* search:: Search devices by file, label, or UUID
* sendkey:: Emulate keystrokes
* set:: Set an environment variable
+* source:: Read a configuration file in same context
* true:: Do nothing, successfully
* unset:: Unset an environment variable
* uppermem:: Set the upper memory size
@@ -3429,7 +3493,9 @@ If they are completely identical, nothing will be printed.
@deffn Command configfile file
Load @var{file} as a configuration file. If @var{file} defines any menu
-entries, then show a menu containing them immediately.
+entries, then show a menu containing them immediately. Any environment
+variable changes made by the commands in @var{file} will not be preserved
+after @command{configfile} returns.
@end deffn
@@ -3467,6 +3533,15 @@ arguments, and set the result as the new date and time. For example, `date
hour, minute, and second unchanged.
@end deffn
+@node devicetree
+@subsection linux
+
+@deffn Command devicetree file
+Load a device tree blob (.dtb) from a filesystem, for later use by a Linux
+kernel. Does not perform merging with any device tree supplied by firmware,
+but rather replaces it completely.
+@ref{GNU/Linux}.
+@end deffn
@node drivemap
@subsection drivemap
@@ -4069,6 +4144,19 @@ arguments, print all environment variables with their values.
@end deffn
+@node source
+@subsection source
+
+@deffn Command source file
+Read @var{file} as a configuration file, as if its contents had been
+incorporated directly into the sourcing file. Unlike @command{configfile}
+(@pxref{configfile}), this executes the contents of @var{file} without
+changing context: any environment variable changes made by the commands in
+@var{file} will be preserved after @command{source} returns, and the menu
+will not be shown immediately.
+@end deffn
+
+
@node true
@subsection true
@@ -4154,7 +4242,7 @@ and tonal writing (2e5-2e9). GRUB also ignores deprecated (as specified
in Unicode) characters (e.g. tags). GRUB also doesn't handle so called
``annotation characters'' If you can complete either of
two lists or, better, propose a patch to improve rendering, please contact
-developper team.
+developer team.
@chapter Input terminal
Firmware console on BIOS, IEEE1275 and ARC doesn't allow you to enter non-ASCII
@@ -4304,6 +4392,8 @@ AT keyboard support allows keyboard layout remapping and support for keys not
available through firmware. It isn't needed for normal operation except
baremetal ports.
+Speaker allows morse and spkmodem communication.
+
USB support provides benefits similar to ATA (for USB disks) or AT (for USB
keyboards). In addition it allows USBserial.
@@ -4325,6 +4415,7 @@ and mips-qemu_mips can use only memory up to first hole.
@item network @tab yes (*) @tab no @tab no @tab no
@item ATA/AHCI @tab yes @tab yes @tab yes @tab yes
@item AT keyboard @tab yes @tab yes @tab yes @tab yes
+@item Speaker @tab yes @tab yes @tab yes @tab yes
@item USB @tab yes @tab yes @tab yes @tab yes
@item chainloader @tab local @tab yes @tab yes @tab no
@item cpuid @tab partial @tab partial @tab partial @tab partial
@@ -4342,6 +4433,7 @@ and mips-qemu_mips can use only memory up to first hole.
@item network @tab yes @tab yes @tab yes @tab yes
@item ATA/AHCI @tab yes @tab yes @tab yes @tab no
@item AT keyboard @tab yes @tab yes @tab yes @tab no
+@item Speaker @tab yes @tab yes @tab yes @tab no
@item USB @tab yes @tab yes @tab yes @tab no
@item chainloader @tab local @tab local @tab no @tab local
@item cpuid @tab partial @tab partial @tab partial @tab no
@@ -4359,6 +4451,7 @@ and mips-qemu_mips can use only memory up to first hole.
@item network @tab no @tab yes (*) @tab yes @tab no
@item ATA/AHCI @tab yes @tab no @tab no @tab no
@item AT keyboard @tab yes @tab no @tab no @tab no
+@item Speaker @tab no @tab no @tab no @tab no
@item USB @tab yes @tab no @tab no @tab no
@item chainloader @tab yes @tab no @tab no @tab no
@item cpuid @tab no @tab no @tab no @tab no
@@ -4376,6 +4469,7 @@ and mips-qemu_mips can use only memory up to first hole.
@item network @tab no @tab yes
@item ATA/AHCI @tab yes @tab no
@item AT keyboard @tab yes @tab no
+@item Speaker @tab no @tab no
@item USB @tab N/A @tab yes
@item chainloader @tab yes @tab no
@item cpuid @tab no @tab no
@@ -4651,9 +4745,9 @@ GRUB.
@node Invoking grub-install
@chapter Invoking grub-install
-The program @command{grub-install} installs GRUB on your drive using
-@command{grub-mkimage} and (on some platforms) @command{grub-setup}. You
-must specify the device name on which you want to install GRUB, like this:
+The program @command{grub-install} generates a GRUB core image using
+@command{grub-mkimage} and installs it on your system. You must specify the
+device name on which you want to install GRUB, like this:
@example
grub-install @var{install_device}
@@ -4756,6 +4850,33 @@ Length of the salt. Defaults to 64.
@end table
+@node Invoking grub-mkrelpath
+@chapter Invoking grub-mkrelpath
+
+The program @command{grub-mkrelpath} makes a file system path relative to
+the root of its containing file system. For instance, if @file{/usr} is a
+mount point, then:
+
+@example
+$ @kbd{grub-mkrelpath /usr/share/grub/unicode.pf2}
+@samp{/share/grub/unicode.pf2}
+@end example
+
+This is mainly used internally by other GRUB utilities such as
+@command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}), but may
+occasionally also be useful for debugging.
+
+@command{grub-mkrelpath} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+@end table
+
+
@node Invoking grub-mkrescue
@chapter Invoking grub-mkrescue
@@ -4814,6 +4935,93 @@ built-in default.
@end table
+@node Invoking grub-mount
+@chapter Invoking grub-mount
+
+The program @command{grub-mount} performs a read-only mount of any file
+system or file system image that GRUB understands, using GRUB's file system
+drivers via FUSE. (It is only available if FUSE development files were
+present when GRUB was built.) This has a number of uses:
+
+@itemize @bullet
+@item
+It provides a convenient way to check how GRUB will view a file system at
+boot time. You can use normal command-line tools to compare that view with
+that of your operating system, making it easy to find bugs.
+
+@item
+It offers true read-only mounts. Linux does not have these for journalling
+file systems, because it will always attempt to replay the journal at mount
+time; while you can temporarily mark the block device read-only to avoid
+this, that causes the mount to fail. Since GRUB intentionally contains no
+code for writing to file systems, it can easily provide a guaranteed
+read-only mount mechanism.
+
+@item
+It allows you to examine any file system that GRUB understands without
+needing to load additional modules into your running kernel, which may be
+useful in constrained environments such as installers.
+
+@item
+Since it can examine file system images (contained in regular files) just as
+easily as file systems on block devices, you can use it to inspect any file
+system image that GRUB understands with only enough privileges to use FUSE,
+even if nobody has yet written a FUSE module specifically for that file
+system type.
+@end itemize
+
+Using @command{grub-mount} is normally as simple as:
+
+@example
+grub-mount /dev/sda1 /mnt
+@end example
+
+@command{grub-mount} must be given one or more images and a mount point as
+non-option arguments (if it is given more than one image, it will treat them
+as a RAID set), and also accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item -C
+@itemx --crypto
+Mount encrypted devices, prompting for a passphrase if necessary.
+
+@item -d @var{string}
+@itemx --debug=@var{string}
+Show debugging output for conditions matching @var{string}.
+
+@item -K prompt|@var{file}
+@itemx --zfs-key=prompt|@var{file}
+Load a ZFS encryption key. If you use @samp{prompt} as the argument,
+@command{grub-mount} will read a passphrase from the terminal; otherwise, it
+will read key material from the specified file.
+
+@item -r @var{device}
+@itemx --root=@var{device}
+Set the GRUB root device to @var{device}. You do not normally need to set
+this; @command{grub-mount} will automatically set the root device to the
+root of the supplied file system.
+
+If @var{device} is just a number, then it will be treated as a partition
+number within the supplied image. This means that, if you have an image of
+an entire disk in @file{disk.img}, then you can use this command to mount
+its second partition:
+
+@example
+grub-mount -r 2 disk.img mount-point
+@end example
+
+@item -v
+@itemx --verbose
+Print verbose messages.
+@end table
+
+
@node Invoking grub-probe
@chapter Invoking grub-probe
@@ -4900,6 +5108,33 @@ Print verbose messages.
@end table
+@node Invoking grub-script-check
+@chapter Invoking grub-script-check
+
+The program @command{grub-script-check} takes a GRUB script file
+(@pxref{Shell-like scripting}) and checks it for syntax errors, similar to
+commands such as @command{sh -n}. It may take a @var{path} as a non-option
+argument; if none is supplied, it will read from standard input.
+
+@example
+grub-script-check /boot/grub/grub.cfg
+@end example
+
+@command{grub-script-check} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item -v
+@itemx --verbose
+Print each line of input after reading it.
+@end table
+
+
@node Obtaining and Building GRUB
@appendix How to obtain and build GRUB
diff --git a/docs/man/grub-bios-setup.h2m b/docs/man/grub-bios-setup.h2m
index eebe3ef..ac6ede3 100644
--- a/docs/man/grub-bios-setup.h2m
+++ b/docs/man/grub-bios-setup.h2m
@@ -1,5 +1,5 @@
[NAME]
-grub-setup \- set up a device to boot using GRUB
+grub-bios-setup \- set up a device to boot using GRUB
[SEE ALSO]
.BR grub-install (8),
.BR grub-mkimage (1),
diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m
index 2de371a..8cbbc87 100644
--- a/docs/man/grub-install.h2m
+++ b/docs/man/grub-install.h2m
@@ -3,5 +3,4 @@ grub-install \- install GRUB to a device
[SEE ALSO]
.BR grub-mkconfig (8),
.BR grub-mkimage (1),
-.BR grub-setup (8),
.BR grub-mkrescue (1)
diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m
index ca08b0c..f0fbc2b 100644
--- a/docs/man/grub-mkimage.h2m
+++ b/docs/man/grub-mkimage.h2m
@@ -2,6 +2,5 @@
grub-mkimage \- make a bootable image of GRUB
[SEE ALSO]
.BR grub-install (8),
-.BR grub-setup (8),
.BR grub-mkrescue (1),
.BR grub-mknetdir (8)
diff --git a/docs/man/grub-sparc64-setup.h2m b/docs/man/grub-sparc64-setup.h2m
index eebe3ef..18f803a 100644
--- a/docs/man/grub-sparc64-setup.h2m
+++ b/docs/man/grub-sparc64-setup.h2m
@@ -1,5 +1,5 @@
[NAME]
-grub-setup \- set up a device to boot using GRUB
+grub-sparc64-setup \- set up a device to boot using GRUB
[SEE ALSO]
.BR grub-install (8),
.BR grub-mkimage (1),
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 8704d23..6bdd53c 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -704,6 +704,13 @@ module = {
};
module = {
+ name = verify;
+ common = commands/verify.c;
+ cflags = '$(CFLAGS_POSIX)';
+ cppflags = '-I$(srcdir)/lib/posix_wrap';
+};
+
+module = {
name = hdparm;
common = commands/hdparm.c;
common = lib/hexdump.c;
@@ -789,6 +796,18 @@ module = {
};
module = {
+ name = spkmodem;
+ x86 = term/spkmodem.c;
+ enable = x86;
+};
+
+module = {
+ name = morse;
+ x86 = term/morse.c;
+ enable = x86;
+};
+
+module = {
name = probe;
common = commands/probe.c;
};
@@ -826,6 +845,12 @@ module = {
};
module = {
+ name = pcidump;
+ common = commands/pcidump.c;
+ enable = pci;
+};
+
+module = {
name = sleep;
common = commands/sleep.c;
};
@@ -1868,6 +1893,36 @@ module = {
};
module = {
+ name = mpi;
+ common = lib/libgcrypt-grub/mpi/mpiutil.c;
+ common = lib/libgcrypt-grub/mpi/mpi-bit.c;
+ common = lib/libgcrypt-grub/mpi/mpi-add.c;
+ common = lib/libgcrypt-grub/mpi/mpi-mul.c;
+ common = lib/libgcrypt-grub/mpi/mpi-mod.c;
+ common = lib/libgcrypt-grub/mpi/mpi-gcd.c;
+ common = lib/libgcrypt-grub/mpi/mpi-div.c;
+ common = lib/libgcrypt-grub/mpi/mpi-cmp.c;
+ common = lib/libgcrypt-grub/mpi/mpi-inv.c;
+ common = lib/libgcrypt-grub/mpi/mpi-pow.c;
+ common = lib/libgcrypt-grub/mpi/mpi-mpow.c;
+ common = lib/libgcrypt-grub/mpi/mpih-lshift.c;
+ common = lib/libgcrypt-grub/mpi/mpih-mul.c;
+ common = lib/libgcrypt-grub/mpi/mpih-mul1.c;
+ common = lib/libgcrypt-grub/mpi/mpih-mul2.c;
+ common = lib/libgcrypt-grub/mpi/mpih-mul3.c;
+ common = lib/libgcrypt-grub/mpi/mpih-add1.c;
+ common = lib/libgcrypt-grub/mpi/mpih-sub1.c;
+ common = lib/libgcrypt-grub/mpi/mpih-div.c;
+ common = lib/libgcrypt-grub/mpi/mpicoder.c;
+ common = lib/libgcrypt-grub/mpi/mpih-rshift.c;
+ common = lib/libgcrypt-grub/mpi/mpi-inline.c;
+ common = lib/libgcrypt_wrap/mem.c;
+
+ cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';
+ cppflags = '$(CPPFLAGS_GCRY)';
+};
+
+module = {
name = all_video;
common = lib/fake_module.c;
};
diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c
index 9e7796e..bb9aa27 100644
--- a/grub-core/bus/cs5536.c
+++ b/grub-core/bus/cs5536.c
@@ -29,28 +29,39 @@
GRUB_MOD_LICENSE ("GPLv3+");
+/* Context for grub_cs5536_find. */
+struct grub_cs5536_find_ctx
+{
+ grub_pci_device_t *devp;
+ int found;
+};
+
+/* Helper for grub_cs5536_find. */
+static int
+grub_cs5536_find_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
+{
+ struct grub_cs5536_find_ctx *ctx = data;
+
+ if (pciid == GRUB_CS5536_PCIID)
+ {
+ *ctx->devp = dev;
+ ctx->found = 1;
+ return 1;
+ }
+ return 0;
+}
+
int
grub_cs5536_find (grub_pci_device_t *devp)
{
- int found = 0;
- auto int NESTED_FUNC_ATTR hook (grub_pci_device_t dev,
- grub_pci_id_t pciid);
-
- int NESTED_FUNC_ATTR hook (grub_pci_device_t dev,
- grub_pci_id_t pciid)
- {
- if (pciid == GRUB_CS5536_PCIID)
- {
- *devp = dev;
- found = 1;
- return 1;
- }
- return 0;
- }
+ struct grub_cs5536_find_ctx ctx = {
+ .devp = devp,
+ .found = 0
+ };
- grub_pci_iterate (hook);
+ grub_pci_iterate (grub_cs5536_find_iter, &ctx);
- return found;
+ return ctx.found;
}
grub_uint64_t
diff --git a/grub-core/bus/emu/pci.c b/grub-core/bus/emu/pci.c
index d1beb56..9d32963 100644
--- a/grub-core/bus/emu/pci.c
+++ b/grub-core/bus/emu/pci.c
@@ -32,7 +32,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg)
}
void
-grub_pci_iterate (grub_pci_iteratefunc_t hook)
+grub_pci_iterate (grub_pci_iteratefunc_t hook, void *hook_data)
{
struct pci_device_iterator *iter;
struct pci_slot_match slot;
@@ -43,7 +43,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook)
slot.func = PCI_MATCH_ANY;
iter = pci_slot_match_iterator_create (&slot);
while ((dev = pci_device_next (iter)))
- hook (dev, dev->vendor_id | (dev->device_id << 16));
+ hook (dev, dev->vendor_id | (dev->device_id << 16), hook_data);
pci_iterator_destroy (iter);
}
diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c
index 17dea30..b388ce5 100644
--- a/grub-core/bus/pci.c
+++ b/grub-core/bus/pci.c
@@ -98,7 +98,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg)
}
void
-grub_pci_iterate (grub_pci_iteratefunc_t hook)
+grub_pci_iterate (grub_pci_iteratefunc_t hook, void *hook_data)
{
grub_pci_device_t dev;
grub_pci_address_t addr;
@@ -125,7 +125,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook)
continue;
}
- if (hook (dev, id))
+ if (hook (dev, id, hook_data))
return;
/* Probe only func = 0 if the device if not multifunction */
diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c
index d99a4be..9215866 100644
--- a/grub-core/bus/usb/ehci.c
+++ b/grub-core/bus/usb/ehci.c
@@ -454,9 +454,9 @@ grub_ehci_reset (struct grub_ehci *e)
}
/* PCI iteration function... */
-static int NESTED_FUNC_ATTR
-grub_ehci_pci_iter (grub_pci_device_t dev,
- grub_pci_id_t pciid __attribute__ ((unused)))
+static int
+grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
{
grub_uint8_t release;
grub_uint32_t class_code;
@@ -870,7 +870,7 @@ fail:
}
static int
-grub_ehci_iterate (int (*hook) (grub_usb_controller_t dev))
+grub_ehci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data)
{
struct grub_ehci *e;
struct grub_usb_controller dev;
@@ -878,7 +878,7 @@ grub_ehci_iterate (int (*hook) (grub_usb_controller_t dev))
for (e = ehci; e; e = e->next)
{
dev.data = e;
- if (hook (&dev))
+ if (hook (&dev, hook_data))
return 1;
}
@@ -1815,7 +1815,7 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
static void
grub_ehci_inithw (void)
{
- grub_pci_iterate (grub_ehci_pci_iter);
+ grub_pci_iterate (grub_ehci_pci_iter, NULL);
}
static grub_err_t
diff --git a/grub-core/bus/usb/emu/usb.c b/grub-core/bus/usb/emu/usb.c
index 38c5f01..3ad2fc3 100644
--- a/grub-core/bus/usb/emu/usb.c
+++ b/grub-core/bus/usb/emu/usb.c
@@ -88,7 +88,7 @@ grub_usb_poll_devices (void)
int
-grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
+grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data)
{
int i;
@@ -96,7 +96,7 @@ grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
{
if (grub_usb_devs[i])
{
- if (hook (grub_usb_devs[i]))
+ if (hook (grub_usb_devs[i], hook_data))
return 1;
}
}
diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c
index 6fabb4b..835bb15 100644
--- a/grub-core/bus/usb/ohci.c
+++ b/grub-core/bus/usb/ohci.c
@@ -213,9 +213,9 @@ grub_ohci_writereg32 (struct grub_ohci *o,
/* Iterate over all PCI devices. Determine if a device is an OHCI
controller. If this is the case, initialize it. */
-static int NESTED_FUNC_ATTR
-grub_ohci_pci_iter (grub_pci_device_t dev,
- grub_pci_id_t pciid)
+static int
+grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
{
grub_uint32_t interf;
grub_uint32_t base;
@@ -477,13 +477,13 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
static void
grub_ohci_inithw (void)
{
- grub_pci_iterate (grub_ohci_pci_iter);
+ grub_pci_iterate (grub_ohci_pci_iter, NULL);
}
static int
-grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev))
+grub_ohci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data)
{
struct grub_ohci *o;
struct grub_usb_controller dev;
@@ -491,7 +491,7 @@ grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev))
for (o = ohci; o; o = o->next)
{
dev.data = o;
- if (hook (&dev))
+ if (hook (&dev, hook_data))
return 1;
}
diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c
index 8f60850..74de392 100644
--- a/grub-core/bus/usb/uhci.c
+++ b/grub-core/bus/usb/uhci.c
@@ -185,9 +185,10 @@ grub_uhci_portstatus (grub_usb_controller_t dev,
/* Iterate over all PCI devices. Determine if a device is an UHCI
controller. If this is the case, initialize it. */
-static int NESTED_FUNC_ATTR
+static int
grub_uhci_pci_iter (grub_pci_device_t dev,
- grub_pci_id_t pciid __attribute__((unused)))
+ grub_pci_id_t pciid __attribute__((unused)),
+ void *data __attribute__ ((unused)))
{
grub_uint32_t class_code;
grub_uint32_t class;
@@ -351,7 +352,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
static void
grub_uhci_inithw (void)
{
- grub_pci_iterate (grub_uhci_pci_iter);
+ grub_pci_iterate (grub_uhci_pci_iter, NULL);
}
static grub_uhci_td_t
@@ -671,7 +672,7 @@ grub_uhci_cancel_transfer (grub_usb_controller_t dev,
}
static int
-grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev))
+grub_uhci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data)
{
struct grub_uhci *u;
struct grub_usb_controller dev;
@@ -679,7 +680,7 @@ grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev))
for (u = uhci; u; u = u->next)
{
dev.data = u;
- if (hook (&dev))
+ if (hook (&dev, hook_data))
return 1;
}
diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c
index fb04e65..6fbf134 100644
--- a/grub-core/bus/usb/usb.c
+++ b/grub-core/bus/usb/usb.c
@@ -29,27 +29,28 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_usb_controller_dev_t grub_usb_list;
static struct grub_usb_attach_desc *attach_hooks;
-void
-grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
+/* Iterate over all controllers found by the driver. */
+static int
+grub_usb_controller_dev_register_iter (grub_usb_controller_t dev, void *data)
{
- auto int iterate_hook (grub_usb_controller_t dev);
+ grub_usb_controller_dev_t usb = data;
- /* Iterate over all controllers found by the driver. */
- int iterate_hook (grub_usb_controller_t dev)
- {
- dev->dev = usb;
+ dev->dev = usb;
- /* Enable the ports of the USB Root Hub. */
- grub_usb_root_hub (dev);
+ /* Enable the ports of the USB Root Hub. */
+ grub_usb_root_hub (dev);
- return 0;
- }
+ return 0;
+}
+void
+grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
+{
usb->next = grub_usb_list;
grub_usb_list = usb;
if (usb->iterate)
- usb->iterate (iterate_hook);
+ usb->iterate (grub_usb_controller_dev_register_iter, usb);
}
void
@@ -66,27 +67,41 @@ grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
}
#if 0
-int
-grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev))
+/* Context for grub_usb_controller_iterate. */
+struct grub_usb_controller_iterate_ctx
{
+ grub_usb_controller_iterate_hook_t hook;
+ void *hook_data;
grub_usb_controller_dev_t p;
+};
- auto int iterate_hook (grub_usb_controller_t dev);
+/* Helper for grub_usb_controller_iterate. */
+static int
+grub_usb_controller_iterate_iter (grub_usb_controller_t dev, void *data)
+{
+ struct grub_usb_controller_iterate_ctx *ctx = data;
- int iterate_hook (grub_usb_controller_t dev)
- {
- dev->dev = p;
- if (hook (dev))
- return 1;
- return 0;
- }
+ dev->dev = ctx->p;
+ if (ctx->hook (dev, ctx->hook_data))
+ return 1;
+ return 0;
+}
+
+int
+grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook,
+ void *hook_data)
+{
+ struct grub_usb_controller_iterate_ctx ctx = {
+ .hook = hook,
+ .hook_data = hook_data
+ };
/* Iterate over all controller drivers. */
- for (p = grub_usb_list; p; p = p->next)
+ for (ctx.p = grub_usb_list; ctx.p; ctx.p = ctx.p->next)
{
/* Iterate over the busses of the controllers. XXX: Actually, a
hub driver should do this. */
- if (p->iterate (iterate_hook))
+ if (ctx.p->iterate (grub_usb_controller_iterate_iter, &ctx))
return 1;
}
@@ -295,46 +310,47 @@ void grub_usb_device_attach (grub_usb_device_t dev)
}
}
-void
-grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc)
+/* Helper for grub_usb_register_attach_hook_class. */
+static int
+grub_usb_register_attach_hook_class_iter (grub_usb_device_t usbdev, void *data)
{
- auto int usb_iterate (grub_usb_device_t dev);
-
- int usb_iterate (grub_usb_device_t usbdev)
- {
- struct grub_usb_desc_device *descdev = &usbdev->descdev;
- int i;
-
- if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0
- || descdev->configcnt == 0)
- return 0;
+ struct grub_usb_attach_desc *desc = data;
+ struct grub_usb_desc_device *descdev = &usbdev->descdev;
+ int i;
- /* XXX: Just check configuration 0 for now. */
- for (i = 0; i < usbdev->config[0].descconf->numif; i++)
- {
- struct grub_usb_desc_if *interf;
+ if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0
+ || descdev->configcnt == 0)
+ return 0;
- interf = usbdev->config[0].interf[i].descif;
+ /* XXX: Just check configuration 0 for now. */
+ for (i = 0; i < usbdev->config[0].descconf->numif; i++)
+ {
+ struct grub_usb_desc_if *interf;
- grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n",
- i, interf->class, interf->subclass, interf->protocol);
+ interf = usbdev->config[0].interf[i].descif;
- if (usbdev->config[0].interf[i].attached)
- continue;
+ grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n",
+ i, interf->class, interf->subclass, interf->protocol);
- if (interf->class != desc->class)
- continue;
- if (desc->hook (usbdev, 0, i))
- usbdev->config[0].interf[i].attached = 1;
- }
+ if (usbdev->config[0].interf[i].attached)
+ continue;
- return 0;
+ if (interf->class != desc->class)
+ continue;
+ if (desc->hook (usbdev, 0, i))
+ usbdev->config[0].interf[i].attached = 1;
}
+ return 0;
+}
+
+void
+grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc)
+{
desc->next = attach_hooks;
attach_hooks = desc;
- grub_usb_iterate (usb_iterate);
+ grub_usb_iterate (grub_usb_register_attach_hook_class_iter, desc);
}
void
diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
index 5fc5eba..3927f51 100644
--- a/grub-core/bus/usb/usbhub.c
+++ b/grub-core/bus/usb/usbhub.c
@@ -556,7 +556,7 @@ grub_usb_poll_devices (void)
}
int
-grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
+grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data)
{
int i;
@@ -564,7 +564,7 @@ grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
{
if (grub_usb_devs[i])
{
- if (hook (grub_usb_devs[i]))
+ if (hook (grub_usb_devs[i], hook_data))
return 1;
}
}
diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c
index 167fae5..154c72d 100644
--- a/grub-core/bus/usb/usbtrans.c
+++ b/grub-core/bus/usb/usbtrans.c
@@ -351,11 +351,23 @@ grub_usb_err_t
grub_usb_bulk_read (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
{
- grub_size_t actual;
+ grub_size_t actual, transferred;
grub_usb_err_t err;
- err = grub_usb_bulk_readwrite (dev, endpoint, size, data,
- GRUB_USB_TRANSFER_TYPE_IN, 1000, &actual);
- if (!err && actual != size)
+ grub_size_t current_size, position;
+
+ for (position = 0, transferred = 0;
+ position < size; position += MAX_USB_TRANSFER_LEN)
+ {
+ current_size = size - position;
+ if (current_size >= MAX_USB_TRANSFER_LEN)
+ current_size = MAX_USB_TRANSFER_LEN;
+ err = grub_usb_bulk_readwrite (dev, endpoint, current_size,
+ &data[position], GRUB_USB_TRANSFER_TYPE_IN, 1000, &actual);
+ transferred += actual;
+ if (err || (current_size != actual) ) break;
+ }
+
+ if (!err && transferred != size)
err = GRUB_USB_ERR_DATA;
return err;
}
diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index c6be5e1..891e392 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -142,49 +142,58 @@ iszero (grub_uint8_t *reg, int size)
}
#if defined (__i386__) || defined (__x86_64__)
+/* Context for grub_acpi_create_ebda. */
+struct grub_acpi_create_ebda_ctx {
+ int ebda_len;
+ grub_uint64_t highestlow;
+};
+
+/* Helper for grub_acpi_create_ebda. */
+static int
+find_hook (grub_uint64_t start, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
+{
+ struct grub_acpi_create_ebda_ctx *ctx = data;
+ grub_uint64_t end = start + size;
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ if (end > 0x100000)
+ end = 0x100000;
+ if (end > start + ctx->ebda_len
+ && ctx->highestlow < ((end - ctx->ebda_len) & (~0xf)) )
+ ctx->highestlow = (end - ctx->ebda_len) & (~0xf);
+ return 0;
+}
+
grub_err_t
grub_acpi_create_ebda (void)
{
+ struct grub_acpi_create_ebda_ctx ctx = {
+ .highestlow = 0
+ };
int ebda_kb_len;
- int ebda_len;
int mmapregion = 0;
grub_uint8_t *ebda, *v1inebda = 0, *v2inebda = 0;
- grub_uint64_t highestlow = 0;
grub_uint8_t *targetebda, *target;
struct grub_acpi_rsdp_v10 *v1;
struct grub_acpi_rsdp_v20 *v2;
- auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
- grub_uint32_t);
- int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size,
- grub_memory_type_t type)
- {
- grub_uint64_t end = start + size;
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
- if (end > 0x100000)
- end = 0x100000;
- if (end > start + ebda_len
- && highestlow < ((end - ebda_len) & (~0xf)) )
- highestlow = (end - ebda_len) & (~0xf);
- return 0;
- }
ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4);
ebda_kb_len = *(grub_uint16_t *) ebda;
if (! ebda || ebda_kb_len > 16)
ebda_kb_len = 0;
- ebda_len = (ebda_kb_len + 1) << 10;
+ ctx.ebda_len = (ebda_kb_len + 1) << 10;
/* FIXME: use low-memory mm allocation once it's available. */
- grub_mmap_iterate (find_hook);
- targetebda = (grub_uint8_t *) (grub_addr_t) highestlow;
+ grub_mmap_iterate (find_hook, &ctx);
+ targetebda = (grub_uint8_t *) (grub_addr_t) ctx.highestlow;
grub_dprintf ("acpi", "creating ebda @%llx\n",
- (unsigned long long) highestlow);
- if (! highestlow)
+ (unsigned long long) ctx.highestlow);
+ if (! ctx.highestlow)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't find space for the new EBDA");
- mmapregion = grub_mmap_register ((grub_addr_t) targetebda, ebda_len,
+ mmapregion = grub_mmap_register ((grub_addr_t) targetebda, ctx.ebda_len,
GRUB_MEMORY_RESERVED);
if (! mmapregion)
return grub_errno;
diff --git a/grub-core/commands/arc/lsdev.c b/grub-core/commands/arc/lsdev.c
index 5d4b0cd..27ed0a2 100644
--- a/grub-core/commands/arc/lsdev.c
+++ b/grub-core/commands/arc/lsdev.c
@@ -24,18 +24,22 @@
GRUB_MOD_LICENSE ("GPLv3+");
+/* Helper for grub_cmd_lsdev. */
+static int
+grub_cmd_lsdev_iter (const char *name,
+ const struct grub_arc_component *comp __attribute__ ((unused)),
+ void *data __attribute__ ((unused)))
+{
+ grub_printf ("%s\n", name);
+ return 0;
+}
+
static grub_err_t
grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
- auto int hook (const char *name, const struct grub_arc_component *comp);
- int hook (const char *name, const struct grub_arc_component *comp __attribute__ ((unused)))
- {
- grub_printf ("%s\n", name);
- return 0;
- }
- grub_arc_iterate_devs (hook, 0);
+ grub_arc_iterate_devs (grub_cmd_lsdev_iter, 0, 0);
return 0;
}
diff --git a/grub-core/commands/efi/fixvideo.c b/grub-core/commands/efi/fixvideo.c
index 3ed40b3..d9d54a2 100644
--- a/grub-core/commands/efi/fixvideo.c
+++ b/grub-core/commands/efi/fixvideo.c
@@ -23,6 +23,7 @@
#include <grub/pci.h>
#include <grub/command.h>
#include <grub/i18n.h>
+#include <grub/mm.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -40,8 +41,9 @@ static struct grub_video_patch
{0, 0, 0, 0, 0}
};
-static int NESTED_FUNC_ATTR
-scan_card (grub_pci_device_t dev, grub_pci_id_t pciid)
+static int
+scan_card (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
{
grub_pci_address_t addr;
@@ -93,7 +95,7 @@ grub_cmd_fixvideo (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
- grub_pci_iterate (scan_card);
+ grub_pci_iterate (scan_card, NULL);
return 0;
}
diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c
index ba33ea2..396a427 100644
--- a/grub-core/commands/hashsum.c
+++ b/grub-core/commands/hashsum.c
@@ -63,7 +63,7 @@ hextoval (char c)
static grub_err_t
hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result)
{
- grub_uint8_t context[hash->contextsize];
+ GRUB_PROPERLY_ALIGNED_ARRAY (context, hash->contextsize);
grub_uint8_t readbuf[4096];
grub_memset (context, 0, sizeof (context));
diff --git a/grub-core/commands/i386/pc/play.c b/grub-core/commands/i386/pc/play.c
index 10a0181..40798c9 100644
--- a/grub-core/commands/i386/pc/play.c
+++ b/grub-core/commands/i386/pc/play.c
@@ -28,80 +28,12 @@
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/time.h>
+#include <grub/speaker.h>
GRUB_MOD_LICENSE ("GPLv3+");
#define BASE_TEMPO (60 * 1000)
-/* The speaker port. */
-#define SPEAKER 0x61
-
-/* If 0, follow state of SPEAKER_DATA bit, otherwise enable output
- from timer 2. */
-#define SPEAKER_TMR2 0x01
-
-/* If SPEAKER_TMR2 is not set, this provides direct input into the
- speaker. Otherwise, this enables or disables the output from the
- timer. */
-#define SPEAKER_DATA 0x02
-
-/* The PIT channel value ports. You can write to and read from them.
- Do not mess with timer 0 or 1. */
-#define PIT_COUNTER_0 0x40
-#define PIT_COUNTER_1 0x41
-#define PIT_COUNTER_2 0x42
-
-/* The frequency of the PIT clock. */
-#define PIT_FREQUENCY 0x1234dd
-
-/* The PIT control port. You can only write to it. Do not mess with
- timer 0 or 1. */
-#define PIT_CTRL 0x43
-#define PIT_CTRL_SELECT_MASK 0xc0
-#define PIT_CTRL_SELECT_0 0x00
-#define PIT_CTRL_SELECT_1 0x40
-#define PIT_CTRL_SELECT_2 0x80
-
-/* Read and load control. */
-#define PIT_CTRL_READLOAD_MASK 0x30
-#define PIT_CTRL_COUNTER_LATCH 0x00 /* Hold timer value until read. */
-#define PIT_CTRL_READLOAD_LSB 0x10 /* Read/load the LSB. */
-#define PIT_CTRL_READLOAD_MSB 0x20 /* Read/load the MSB. */
-#define PIT_CTRL_READLOAD_WORD 0x30 /* Read/load the LSB then the MSB. */
-
-/* Mode control. */
-#define PIT_CTRL_MODE_MASK 0x0e
-
-/* Interrupt on terminal count. Setting the mode sets output to low.
- When counter is set and terminated, output is set to high. */
-#define PIT_CTRL_INTR_ON_TERM 0x00
-
-/* Programmable one-shot. When loading counter, output is set to
- high. When counter terminated, output is set to low. Can be
- triggered again from that point on by setting the gate pin to
- high. */
-#define PIT_CTRL_PROGR_ONE_SHOT 0x02
-
-/* Rate generator. Output is low for one period of the counter, and
- high for the other. */
-#define PIT_CTRL_RATE_GEN 0x04
-
-/* Square wave generator. Output is low for one half of the period,
- and high for the other half. */
-#define PIT_CTRL_SQUAREWAVE_GEN 0x06
-
-/* Software triggered strobe. Setting the mode sets output to high.
- When counter is set and terminated, output is set to low. */
-#define PIT_CTRL_SOFTSTROBE 0x08
-
-/* Hardware triggered strobe. Like software triggered strobe, but
- only starts the counter when the gate pin is set to high. */
-#define PIT_CTRL_HARDSTROBE 0x0a
-
-/* Count mode. */
-#define PIT_CTRL_COUNT_MASK 0x01
-#define PIT_CTRL_COUNT_BINARY 0x00 /* 16-bit binary counter. */
-#define PIT_CTRL_COUNT_BCD 0x01 /* 4-decade BCD counter. */
#define T_REST ((grub_uint16_t) 0)
#define T_FINE ((grub_uint16_t) -1)
@@ -112,39 +44,6 @@ struct note
grub_uint16_t duration;
};
-static void
-beep_off (void)
-{
- unsigned char status;
-
- status = grub_inb (SPEAKER);
- grub_outb (status & ~(SPEAKER_TMR2 | SPEAKER_DATA), SPEAKER);
-}
-
-static void
-beep_on (grub_uint16_t pitch)
-{
- unsigned char status;
- unsigned int counter;
-
- if (pitch < 20)
- pitch = 20;
- else if (pitch > 20000)
- pitch = 20000;
-
- counter = PIT_FREQUENCY / pitch;
-
- /* Program timer 2. */
- grub_outb (PIT_CTRL_SELECT_2 | PIT_CTRL_READLOAD_WORD
- | PIT_CTRL_SQUAREWAVE_GEN | PIT_CTRL_COUNT_BINARY, PIT_CTRL);
- grub_outb (counter & 0xff, PIT_COUNTER_2); /* LSB */
- grub_outb ((counter >> 8) & 0xff, PIT_COUNTER_2); /* MSB */
-
- /* Start speaker. */
- status = grub_inb (SPEAKER);
- grub_outb (status | SPEAKER_TMR2 | SPEAKER_DATA, SPEAKER);
-}
-
/* Returns whether playing should continue. */
static int
play (unsigned tempo, struct note *note)
@@ -160,11 +59,11 @@ play (unsigned tempo, struct note *note)
switch (note->pitch)
{
case T_REST:
- beep_off ();
+ grub_speaker_beep_off ();
break;
default:
- beep_on (note->pitch);
+ grub_speaker_beep_on (note->pitch);
break;
}
@@ -263,7 +162,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
}
}
- beep_off ();
+ grub_speaker_beep_off ();
return 0;
}
diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c
index 17f648d..d985cb3 100644
--- a/grub-core/commands/i386/pc/sendkey.c
+++ b/grub-core/commands/i386/pc/sendkey.c
@@ -286,47 +286,48 @@ grub_sendkey_preboot (int noret __attribute__ ((unused)))
return GRUB_ERR_NONE;
}
-static grub_err_t
-grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args)
+/* Helper for grub_cmd_sendkey. */
+static int
+find_key_code (char *key)
{
- struct grub_arg_list *state = ctxt->state;
-
- auto int find_key_code (char *key);
- auto int find_ascii_code (char *key);
+ unsigned i;
- int find_key_code (char *key)
+ for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
{
- unsigned i;
+ if (keysym_table[i].unshifted_name
+ && grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
+ return keysym_table[i].keycode;
+ else if (keysym_table[i].shifted_name
+ && grub_strcmp (key, keysym_table[i].shifted_name) == 0)
+ return keysym_table[i].keycode;
+ }
- for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
- {
- if (keysym_table[i].unshifted_name
- && grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
- return keysym_table[i].keycode;
- else if (keysym_table[i].shifted_name
- && grub_strcmp (key, keysym_table[i].shifted_name) == 0)
- return keysym_table[i].keycode;
- }
+ return 0;
+}
- return 0;
- }
+/* Helper for grub_cmd_sendkey. */
+static int
+find_ascii_code (char *key)
+{
+ unsigned i;
- int find_ascii_code (char *key)
+ for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
{
- unsigned i;
+ if (keysym_table[i].unshifted_name
+ && grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
+ return keysym_table[i].unshifted_ascii;
+ else if (keysym_table[i].shifted_name
+ && grub_strcmp (key, keysym_table[i].shifted_name) == 0)
+ return keysym_table[i].shifted_ascii;
+ }
- for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
- {
- if (keysym_table[i].unshifted_name
- && grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
- return keysym_table[i].unshifted_ascii;
- else if (keysym_table[i].shifted_name
- && grub_strcmp (key, keysym_table[i].shifted_name) == 0)
- return keysym_table[i].shifted_ascii;
- }
+ return 0;
+}
- return 0;
- }
+static grub_err_t
+grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ struct grub_arg_list *state = ctxt->state;
andmask = 0xffffffff;
ormask = 0;
diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
index 5293acc..a3ad5c6 100644
--- a/grub-core/commands/legacycfg.c
+++ b/grub-core/commands/legacycfg.c
@@ -35,6 +35,15 @@
GRUB_MOD_LICENSE ("GPLv3+");
+/* Helper for legacy_file. */
+static grub_err_t
+legacy_file_getline (char **line, int cont __attribute__ ((unused)),
+ void *data __attribute__ ((unused)))
+{
+ *line = 0;
+ return GRUB_ERR_NONE;
+}
+
static grub_err_t
legacy_file (const char *filename)
{
@@ -43,14 +52,6 @@ legacy_file (const char *filename)
grub_menu_t menu;
char *suffix = grub_strdup ("");
- auto grub_err_t getline (char **line, int cont);
- grub_err_t getline (char **line,
- int cont __attribute__ ((unused)))
- {
- *line = 0;
- return GRUB_ERR_NONE;
- }
-
if (!suffix)
return grub_errno;
@@ -134,7 +135,7 @@ legacy_file (const char *filename)
if (parsed && !entryname)
{
- grub_normal_parse_line (parsed, getline);
+ grub_normal_parse_line (parsed, legacy_file_getline, NULL);
grub_print_error ();
grub_free (parsed);
parsed = NULL;
@@ -180,7 +181,7 @@ legacy_file (const char *filename)
grub_free (args);
}
- grub_normal_parse_line (suffix, getline);
+ grub_normal_parse_line (suffix, legacy_file_getline, NULL);
grub_print_error ();
grub_free (suffix);
grub_free (entrysrc);
diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c
index 18ebb7e..9a35550 100644
--- a/grub-core/commands/loadenv.c
+++ b/grub-core/commands/loadenv.c
@@ -114,6 +114,14 @@ read_envblk_file (grub_file_t file)
return envblk;
}
+/* Helper for grub_cmd_load_env. */
+static int
+set_var (const char *name, const char *value)
+{
+ grub_env_set (name, value);
+ return 0;
+}
+
static grub_err_t
grub_cmd_load_env (grub_extcmd_context_t ctxt,
int argc __attribute__ ((unused)),
@@ -123,13 +131,6 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt,
grub_file_t file;
grub_envblk_t envblk;
- auto int set_var (const char *name, const char *value);
- int set_var (const char *name, const char *value)
- {
- grub_env_set (name, value);
- return 0;
- }
-
file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
if (! file)
return grub_errno;
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
index 913bb65..83930aa 100644
--- a/grub-core/commands/ls.c
+++ b/grub-core/commands/ls.c
@@ -45,21 +45,24 @@ static const struct grub_arg_option options[] =
static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'};
-static grub_err_t
-grub_ls_list_devices (int longlist)
+/* Helper for grub_ls_list_devices. */
+static int
+grub_ls_print_devices (const char *name, void *data)
{
- auto int grub_ls_print_devices (const char *name);
- int grub_ls_print_devices (const char *name)
- {
- if (longlist)
- grub_normal_print_device_info (name);
- else
- grub_printf ("(%s) ", name);
+ int *longlist = data;
- return 0;
- }
+ if (*longlist)
+ grub_normal_print_device_info (name);
+ else
+ grub_printf ("(%s) ", name);
- grub_device_iterate (grub_ls_print_devices);
+ return 0;
+}
+
+static grub_err_t
+grub_ls_list_devices (int longlist)
+{
+ grub_device_iterate (grub_ls_print_devices, &longlist);
grub_xputs ("\n");
#if 0
@@ -82,114 +85,126 @@ grub_ls_list_devices (int longlist)
return 0;
}
-static grub_err_t
-grub_ls_list_files (char *dirname, int longlist, int all, int human)
+/* Context for grub_ls_list_files. */
+struct grub_ls_list_files_ctx
{
- char *device_name;
- grub_fs_t fs;
- const char *path;
- grub_device_t dev;
+ char *dirname;
+ int all;
+ int human;
+};
+
+/* Helper for grub_ls_list_files. */
+static int
+print_files (const char *filename, const struct grub_dirhook_info *info,
+ void *data)
+{
+ struct grub_ls_list_files_ctx *ctx = data;
- auto int print_files (const char *filename,
- const struct grub_dirhook_info *info);
- auto int print_files_long (const char *filename,
- const struct grub_dirhook_info *info);
+ if (ctx->all || filename[0] != '.')
+ grub_printf ("%s%s ", filename, info->dir ? "/" : "");
- int print_files (const char *filename, const struct grub_dirhook_info *info)
- {
- if (all || filename[0] != '.')
- grub_printf ("%s%s ", filename, info->dir ? "/" : "");
+ return 0;
+}
- return 0;
- }
+/* Helper for grub_ls_list_files. */
+static int
+print_files_long (const char *filename, const struct grub_dirhook_info *info,
+ void *data)
+{
+ struct grub_ls_list_files_ctx *ctx = data;
- int print_files_long (const char *filename,
- const struct grub_dirhook_info *info)
+ if ((! ctx->all) && (filename[0] == '.'))
+ return 0;
+
+ if (! info->dir)
{
- if ((! all) && (filename[0] == '.'))
- return 0;
+ grub_file_t file;
+ char *pathname;
- if (! info->dir)
- {
- grub_file_t file;
- char *pathname;
+ if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/')
+ pathname = grub_xasprintf ("%s%s", ctx->dirname, filename);
+ else
+ pathname = grub_xasprintf ("%s/%s", ctx->dirname, filename);
- if (dirname[grub_strlen (dirname) - 1] == '/')
- pathname = grub_xasprintf ("%s%s", dirname, filename);
- else
- pathname = grub_xasprintf ("%s/%s", dirname, filename);
+ if (!pathname)
+ return 1;
+
+ /* XXX: For ext2fs symlinks are detected as files while they
+ should be reported as directories. */
+ grub_file_filter_disable_compression ();
+ file = grub_file_open (pathname);
+ if (! file)
+ {
+ grub_errno = 0;
+ grub_free (pathname);
+ return 0;
+ }
- if (!pathname)
- return 1;
+ if (! ctx->human)
+ grub_printf ("%-12llu", (unsigned long long) file->size);
+ else
+ {
+ grub_uint64_t fsize = file->size * 100ULL;
+ grub_uint64_t fsz = file->size;
+ int units = 0;
+ char buf[20];
- /* XXX: For ext2fs symlinks are detected as files while they
- should be reported as directories. */
- grub_file_filter_disable_compression ();
- file = grub_file_open (pathname);
- if (! file)
+ while (fsz / 1024)
{
- grub_errno = 0;
- grub_free (pathname);
- return 0;
+ fsize = (fsize + 512) / 1024;
+ fsz /= 1024;
+ units++;
}
- if (! human)
- grub_printf ("%-12llu", (unsigned long long) file->size);
- else
+ if (units)
{
- grub_uint64_t fsize = file->size * 100ULL;
- grub_uint64_t fsz = file->size;
- int units = 0;
- char buf[20];
-
- while (fsz / 1024)
- {
- fsize = (fsize + 512) / 1024;
- fsz /= 1024;
- units++;
- }
-
- if (units)
- {
- grub_uint64_t whole, fraction;
-
- whole = grub_divmod64 (fsize, 100, &fraction);
- grub_snprintf (buf, sizeof (buf),
- "%" PRIuGRUB_UINT64_T
- ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction,
- grub_human_sizes[units]);
- grub_printf ("%-12s", buf);
- }
- else
- grub_printf ("%-12llu", (unsigned long long) file->size);
-
+ grub_uint64_t whole, fraction;
+
+ whole = grub_divmod64 (fsize, 100, &fraction);
+ grub_snprintf (buf, sizeof (buf),
+ "%" PRIuGRUB_UINT64_T
+ ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction,
+ grub_human_sizes[units]);
+ grub_printf ("%-12s", buf);
}
- grub_file_close (file);
- grub_free (pathname);
- }
- else
- grub_printf ("%-12s", _("DIR"));
-
- if (info->mtimeset)
- {
- struct grub_datetime datetime;
- grub_unixtime2datetime (info->mtime, &datetime);
- if (human)
- grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ",
- datetime.year, datetime.month, datetime.day,
- datetime.hour, datetime.minute,
- datetime.second,
- grub_get_weekday_name (&datetime));
else
- grub_printf (" %04d%02d%02d%02d%02d%02d ",
- datetime.year, datetime.month,
- datetime.day, datetime.hour,
- datetime.minute, datetime.second);
+ grub_printf ("%-12llu", (unsigned long long) file->size);
+
}
- grub_printf ("%s%s\n", filename, info->dir ? "/" : "");
+ grub_file_close (file);
+ grub_free (pathname);
+ }
+ else
+ grub_printf ("%-12s", _("DIR"));
- return 0;
+ if (info->mtimeset)
+ {
+ struct grub_datetime datetime;
+ grub_unixtime2datetime (info->mtime, &datetime);
+ if (ctx->human)
+ grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ",
+ datetime.year, datetime.month, datetime.day,
+ datetime.hour, datetime.minute,
+ datetime.second,
+ grub_get_weekday_name (&datetime));
+ else
+ grub_printf (" %04d%02d%02d%02d%02d%02d ",
+ datetime.year, datetime.month,
+ datetime.day, datetime.hour,
+ datetime.minute, datetime.second);
}
+ grub_printf ("%s%s\n", filename, info->dir ? "/" : "");
+
+ return 0;
+}
+
+static grub_err_t
+grub_ls_list_files (char *dirname, int longlist, int all, int human)
+{
+ char *device_name;
+ grub_fs_t fs;
+ const char *path;
+ grub_device_t dev;
device_name = grub_file_get_device_name (dirname);
dev = grub_device_open (device_name);
@@ -218,10 +233,16 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
}
else if (fs)
{
+ struct grub_ls_list_files_ctx ctx = {
+ .dirname = dirname,
+ .all = all,
+ .human = human
+ };
+
if (longlist)
- (fs->dir) (dev, path, print_files_long);
+ (fs->dir) (dev, path, print_files_long, &ctx);
else
- (fs->dir) (dev, path, print_files);
+ (fs->dir) (dev, path, print_files, &ctx);
if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
&& path[grub_strlen (path) - 1] != '/')
@@ -247,9 +268,9 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
all = 1;
grub_memset (&info, 0, sizeof (info));
if (longlist)
- print_files_long (p, &info);
+ print_files_long (p, &info, &ctx);
else
- print_files (p, &info);
+ print_files (p, &info, &ctx);
grub_free (dirname);
}
diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c
index bd32c33..c1a05d8 100644
--- a/grub-core/commands/lsmmap.c
+++ b/grub-core/commands/lsmmap.c
@@ -21,9 +21,11 @@
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/memory.h>
+#include <grub/mm.h>
GRUB_MOD_LICENSE ("GPLv3+");
+#ifndef GRUB_MACHINE_EMU
static const char *names[] =
{
[GRUB_MEMORY_AVAILABLE] = N_("available RAM"),
@@ -39,26 +41,29 @@ static const char *names[] =
[GRUB_MEMORY_HOLE] = N_("Address range not associated with RAM")
};
+/* Helper for grub_cmd_lsmmap. */
+static int
+lsmmap_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data __attribute__ ((unused)))
+{
+ if (type < ARRAY_SIZE (names) && names[type])
+ grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, %s\n"),
+ (long long) addr, (long long) size, _(names[type]));
+ else
+ grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n"),
+ (long long) addr, (long long) size, type);
+ return 0;
+}
+#endif
+
static grub_err_t
grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- if (type < ARRAY_SIZE (names) && names[type])
- grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, %s\n"),
- (long long) addr, (long long) size, _(names[type]));
- else
- grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n"),
- (long long) addr, (long long) size, type);
- return 0;
- }
#ifndef GRUB_MACHINE_EMU
- grub_machine_mmap_iterate (hook);
+ grub_machine_mmap_iterate (lsmmap_hook, NULL);
#endif
return 0;
diff --git a/grub-core/commands/lspci.c b/grub-core/commands/lspci.c
index 9f83629..65213a3 100644
--- a/grub-core/commands/lspci.c
+++ b/grub-core/commands/lspci.c
@@ -22,6 +22,7 @@
#include <grub/misc.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
+#include <grub/mm.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -126,8 +127,9 @@ static const struct grub_arg_option options[] =
static int iospace;
-static int NESTED_FUNC_ATTR
-grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
+static int
+grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
{
grub_uint32_t class;
const char *sclass;
@@ -218,7 +220,7 @@ grub_cmd_lspci (grub_extcmd_context_t ctxt,
char **args __attribute__ ((unused)))
{
iospace = ctxt->state[0].set;
- grub_pci_iterate (grub_lspci_iter);
+ grub_pci_iterate (grub_lspci_iter, NULL);
return GRUB_ERR_NONE;
}
diff --git a/grub-core/commands/pcidump.c b/grub-core/commands/pcidump.c
new file mode 100644
index 0000000..a49cf93
--- /dev/null
+++ b/grub-core/commands/pcidump.c
@@ -0,0 +1,165 @@
+/* lspci.c - List PCI devices. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/pci.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/env.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_uint32_t pciid_check_mask, pciid_check_value;
+static int bus, device, function;
+static int check_bus, check_device, check_function;
+
+static const struct grub_arg_option options[] =
+ {
+ {0, 'd', 0, N_("Select device by vendor and device IDs."),
+ N_("[vendor]:[device]"), ARG_TYPE_STRING},
+ {0, 's', 0, N_("Select device by its position on the bus."),
+ N_("[bus]:[slot][.func]"), ARG_TYPE_STRING},
+ {0, 0, 0, 0, 0, 0}
+ };
+
+static int
+grub_pcidump_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
+{
+ grub_pci_address_t addr;
+ int i;
+
+ if ((pciid & pciid_check_mask) != pciid_check_value)
+ return 0;
+
+ if (check_bus && grub_pci_get_bus (dev) != bus)
+ return 0;
+
+ if (check_device && grub_pci_get_device (dev) != device)
+ return 0;
+
+ if (check_function && grub_pci_get_function (dev) != function)
+ return 0;
+
+ for (i = 0; i < 256; i += 4)
+ {
+ addr = grub_pci_make_address (dev, i);
+ grub_printf ("%08x ", grub_pci_read (addr));
+ if ((i & 0xc) == 0xc)
+ grub_printf ("\n");
+ }
+
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_pcidump (grub_extcmd_context_t ctxt,
+ int argc __attribute__ ((unused)),
+ char **argv __attribute__ ((unused)))
+{
+ const char *ptr;
+
+ pciid_check_value = 0;
+ pciid_check_mask = 0;
+
+ if (ctxt->state[0].set)
+ {
+ ptr = ctxt->state[0].arg;
+ pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
+ if (grub_errno == GRUB_ERR_BAD_NUMBER)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ ptr = ctxt->state[0].arg;
+ }
+ else
+ pciid_check_mask |= 0xffff;
+ if (grub_errno)
+ return grub_errno;
+ if (*ptr != ':')
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
+ ptr++;
+ pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff)
+ << 16;
+ if (grub_errno == GRUB_ERR_BAD_NUMBER)
+ grub_errno = GRUB_ERR_NONE;
+ else
+ pciid_check_mask |= 0xffff0000;
+ }
+
+ pciid_check_value &= pciid_check_mask;
+
+ check_bus = check_device = check_function = 0;
+
+ if (ctxt->state[1].set)
+ {
+ const char *optr;
+
+ ptr = ctxt->state[1].arg;
+ optr = ptr;
+ bus = grub_strtoul (ptr, (char **) &ptr, 16);
+ if (grub_errno == GRUB_ERR_BAD_NUMBER)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ ptr = optr;
+ }
+ else
+ check_bus = 1;
+ if (grub_errno)
+ return grub_errno;
+ if (*ptr != ':')
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
+ ptr++;
+ optr = ptr;
+ device = grub_strtoul (ptr, (char **) &ptr, 16);
+ if (grub_errno == GRUB_ERR_BAD_NUMBER)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ ptr = optr;
+ }
+ else
+ check_device = 1;
+ if (*ptr == '.')
+ {
+ ptr++;
+ function = grub_strtoul (ptr, (char **) &ptr, 16);
+ if (grub_errno)
+ return grub_errno;
+ check_function = 1;
+ }
+ }
+
+ grub_pci_iterate (grub_pcidump_iter, NULL);
+ return GRUB_ERR_NONE;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(setpci)
+{
+ cmd = grub_register_extcmd ("pcidump", grub_cmd_pcidump, 0,
+ N_("[-s POSITION] [-d DEVICE]"),
+ N_("Dump PCI configuration space."), options);
+}
+
+GRUB_MOD_FINI(setpci)
+{
+ grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 5e9b7e3..16143a3 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -42,23 +42,29 @@ struct cache_entry
static struct cache_entry *cache;
-void
-FUNC_NAME (const char *key, const char *var, int no_floppy,
- char **hints, unsigned nhints)
+/* Context for FUNC_NAME. */
+struct search_ctx
{
- int count = 0;
- int is_cache = 0;
- grub_fs_autoload_hook_t saved_autoload;
+ const char *key;
+ const char *var;
+ int no_floppy;
+ char **hints;
+ unsigned nhints;
+ int count;
+ int is_cache;
+};
- auto int iterate_device (const char *name);
- int iterate_device (const char *name)
- {
- int found = 0;
+/* Helper for FUNC_NAME. */
+static int
+iterate_device (const char *name, void *data)
+{
+ struct search_ctx *ctx = data;
+ int found = 0;
- /* Skip floppy drives when requested. */
- if (no_floppy &&
- name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
- return 0;
+ /* Skip floppy drives when requested. */
+ if (ctx->no_floppy &&
+ name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
+ return 0;
#ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp
@@ -67,34 +73,34 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
#endif
#ifdef DO_SEARCH_FILE
- {
- char *buf;
- grub_file_t file;
-
- buf = grub_xasprintf ("(%s)%s", name, key);
- if (! buf)
- return 1;
-
- grub_file_filter_disable_compression ();
- file = grub_file_open (buf);
- if (file)
- {
- found = 1;
- grub_file_close (file);
- }
- grub_free (buf);
- }
+ {
+ char *buf;
+ grub_file_t file;
+
+ buf = grub_xasprintf ("(%s)%s", name, ctx->key);
+ if (! buf)
+ return 1;
+
+ grub_file_filter_disable_compression ();
+ file = grub_file_open (buf);
+ if (file)
+ {
+ found = 1;
+ grub_file_close (file);
+ }
+ grub_free (buf);
+ }
#else
- {
- /* SEARCH_FS_UUID or SEARCH_LABEL */
- grub_device_t dev;
- grub_fs_t fs;
- char *quid;
+ {
+ /* SEARCH_FS_UUID or SEARCH_LABEL */
+ grub_device_t dev;
+ grub_fs_t fs;
+ char *quid;
- dev = grub_device_open (name);
- if (dev)
- {
- fs = grub_fs_probe (dev);
+ dev = grub_device_open (name);
+ if (dev)
+ {
+ fs = grub_fs_probe (dev);
#ifdef DO_SEARCH_FS_UUID
#define read_fn uuid
@@ -102,173 +108,191 @@ FUNC_NAME (const char *key, const char *var, int no_floppy,
#define read_fn label
#endif
- if (fs && fs->read_fn)
- {
- fs->read_fn (dev, &quid);
+ if (fs && fs->read_fn)
+ {
+ fs->read_fn (dev, &quid);
- if (grub_errno == GRUB_ERR_NONE && quid)
- {
- if (compare_fn (quid, key) == 0)
- found = 1;
+ if (grub_errno == GRUB_ERR_NONE && quid)
+ {
+ if (compare_fn (quid, ctx->key) == 0)
+ found = 1;
- grub_free (quid);
- }
- }
+ grub_free (quid);
+ }
+ }
- grub_device_close (dev);
- }
- }
+ grub_device_close (dev);
+ }
+ }
#endif
- if (!is_cache && found && count == 0)
- {
- struct cache_entry *cache_ent;
- cache_ent = grub_malloc (sizeof (*cache_ent));
- if (cache_ent)
- {
- cache_ent->key = grub_strdup (key);
- cache_ent->value = grub_strdup (name);
- if (cache_ent->value && cache_ent->key)
- {
- cache_ent->next = cache;
- cache = cache_ent;
- }
- else
- {
- grub_free (cache_ent->value);
- grub_free (cache_ent->key);
- grub_free (cache_ent);
- grub_errno = GRUB_ERR_NONE;
- }
- }
- else
- grub_errno = GRUB_ERR_NONE;
- }
-
- if (found)
- {
- count++;
- if (var)
- grub_env_set (var, name);
- else
- grub_printf (" %s", name);
- }
-
- grub_errno = GRUB_ERR_NONE;
- return (found && var);
- }
-
- auto int part_hook (grub_disk_t disk, const grub_partition_t partition);
- int part_hook (grub_disk_t disk, const grub_partition_t partition)
- {
- char *partition_name, *devname;
- int ret;
-
- partition_name = grub_partition_get_name (partition);
- if (! partition_name)
- return 1;
-
- devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
- grub_free (partition_name);
- if (!devname)
- return 1;
- ret = iterate_device (devname);
- grub_free (devname);
-
- return ret;
- }
-
- auto void try (void);
- void try (void)
- {
- unsigned i;
- struct cache_entry **prev;
- struct cache_entry *cache_ent;
-
- for (prev = &cache, cache_ent = *prev; cache_ent;
- prev = &cache_ent->next, cache_ent = *prev)
- if (compare_fn (cache_ent->key, key) == 0)
- break;
- if (cache_ent)
- {
- is_cache = 1;
- if (iterate_device (cache_ent->value))
- {
- is_cache = 0;
- return;
- }
- is_cache = 0;
- /* Cache entry was outdated. Remove it. */
- if (!count)
- {
- grub_free (cache_ent->key);
- grub_free (cache_ent->value);
- grub_free (cache_ent);
- *prev = cache_ent->next;
- }
- }
-
- for (i = 0; i < nhints; i++)
- {
- char *end;
- if (!hints[i][0])
- continue;
- end = hints[i] + grub_strlen (hints[i]) - 1;
- if (*end == ',')
- *end = 0;
- if (iterate_device (hints[i]))
- {
- if (!*end)
- *end = ',';
+ if (!ctx->is_cache && found && ctx->count == 0)
+ {
+ struct cache_entry *cache_ent;
+ cache_ent = grub_malloc (sizeof (*cache_ent));
+ if (cache_ent)
+ {
+ cache_ent->key = grub_strdup (ctx->key);
+ cache_ent->value = grub_strdup (name);
+ if (cache_ent->value && cache_ent->key)
+ {
+ cache_ent->next = cache;
+ cache = cache_ent;
+ }
+ else
+ {
+ grub_free (cache_ent->value);
+ grub_free (cache_ent->key);
+ grub_free (cache_ent);
+ grub_errno = GRUB_ERR_NONE;
+ }
+ }
+ else
+ grub_errno = GRUB_ERR_NONE;
+ }
+
+ if (found)
+ {
+ ctx->count++;
+ if (ctx->var)
+ grub_env_set (ctx->var, name);
+ else
+ grub_printf (" %s", name);
+ }
+
+ grub_errno = GRUB_ERR_NONE;
+ return (found && ctx->var);
+}
+
+/* Helper for FUNC_NAME. */
+static int
+part_hook (grub_disk_t disk, const grub_partition_t partition, void *data)
+{
+ struct search_ctx *ctx = data;
+ char *partition_name, *devname;
+ int ret;
+
+ partition_name = grub_partition_get_name (partition);
+ if (! partition_name)
+ return 1;
+
+ devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
+ grub_free (partition_name);
+ if (!devname)
+ return 1;
+ ret = iterate_device (devname, ctx);
+ grub_free (devname);
+
+ return ret;
+}
+
+/* Helper for FUNC_NAME. */
+static void
+try (struct search_ctx *ctx)
+{
+ unsigned i;
+ struct cache_entry **prev;
+ struct cache_entry *cache_ent;
+
+ for (prev = &cache, cache_ent = *prev; cache_ent;
+ prev = &cache_ent->next, cache_ent = *prev)
+ if (compare_fn (cache_ent->key, ctx->key) == 0)
+ break;
+ if (cache_ent)
+ {
+ ctx->is_cache = 1;
+ if (iterate_device (cache_ent->value, ctx))
+ {
+ ctx->is_cache = 0;
+ return;
+ }
+ ctx->is_cache = 0;
+ /* Cache entry was outdated. Remove it. */
+ if (!ctx->count)
+ {
+ grub_free (cache_ent->key);
+ grub_free (cache_ent->value);
+ grub_free (cache_ent);
+ *prev = cache_ent->next;
+ }
+ }
+
+ for (i = 0; i < ctx->nhints; i++)
+ {
+ char *end;
+ if (!ctx->hints[i][0])
+ continue;
+ end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1;
+ if (*end == ',')
+ *end = 0;
+ if (iterate_device (ctx->hints[i], ctx))
+ {
+ if (!*end)
+ *end = ',';
+ return;
+ }
+ if (!*end)
+ {
+ grub_device_t dev;
+ int ret;
+ dev = grub_device_open (ctx->hints[i]);
+ if (!dev)
+ {
+ if (!*end)
+ *end = ',';
+ continue;
+ }
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
+ if (!*end)
+ *end = ',';
+ continue;
+ }
+ ret = grub_partition_iterate (dev->disk, part_hook, ctx);
+ if (!*end)
+ *end = ',';
+ grub_device_close (dev);
+ if (ret)
return;
- }
- if (!*end)
- {
- grub_device_t dev;
- int ret;
- dev = grub_device_open (hints[i]);
- if (!dev)
- {
- if (!*end)
- *end = ',';
- continue;
- }
- if (!dev->disk)
- {
- grub_device_close (dev);
- if (!*end)
- *end = ',';
- continue;
- }
- ret = grub_partition_iterate (dev->disk, part_hook);
- if (!*end)
- *end = ',';
- grub_device_close (dev);
- if (ret)
- return;
- }
- }
- grub_device_iterate (iterate_device);
- }
+ }
+ }
+ grub_device_iterate (iterate_device, ctx);
+}
+
+void
+FUNC_NAME (const char *key, const char *var, int no_floppy,
+ char **hints, unsigned nhints)
+{
+ struct search_ctx ctx = {
+ .key = key,
+ .var = var,
+ .no_floppy = no_floppy,
+ .hints = hints,
+ .nhints = nhints,
+ .count = 0,
+ .is_cache = 0
+ };
+ grub_fs_autoload_hook_t saved_autoload;
/* First try without autoloading if we're setting variable. */
if (var)
{
saved_autoload = grub_fs_autoload_hook;
grub_fs_autoload_hook = 0;
- try ();
+ try (&ctx);
/* Restore autoload hook. */
grub_fs_autoload_hook = saved_autoload;
/* Retry with autoload if nothing found. */
- if (grub_errno == GRUB_ERR_NONE && count == 0)
- try ();
+ if (grub_errno == GRUB_ERR_NONE && ctx.count == 0)
+ try (&ctx);
}
else
- try ();
+ try (&ctx);
- if (grub_errno == GRUB_ERR_NONE && count == 0)
+ if (grub_errno == GRUB_ERR_NONE && ctx.count == 0)
grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
}
diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c
index fcfec40..d5bc97d 100644
--- a/grub-core/commands/setpci.c
+++ b/grub-core/commands/setpci.c
@@ -83,8 +83,9 @@ static int regsize;
static grub_uint16_t regaddr;
static const char *varname;
-static int NESTED_FUNC_ATTR
-grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
+static int
+grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
{
grub_uint32_t regval = 0;
grub_pci_address_t addr;
@@ -128,7 +129,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
if (!write_mask)
{
- grub_printf (_("Register %x of %d:%d.%d is %x\n"), regaddr,
+ grub_printf (_("Register %x of %x:%02x.%x is %x\n"), regaddr,
grub_pci_get_bus (dev),
grub_pci_get_device (dev),
grub_pci_get_function (dev),
@@ -320,7 +321,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"option -v isn't valid for writes");
- grub_pci_iterate (grub_setpci_iter);
+ grub_pci_iterate (grub_setpci_iter, NULL);
return GRUB_ERR_NONE;
}
@@ -330,7 +331,7 @@ GRUB_MOD_INIT(setpci)
{
cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, 0,
N_("[-s POSITION] [-d DEVICE] [-v VAR] "
- "[REGISTER][=VALUE[:MASK]]"),
+ "REGISTER[=VALUE[:MASK]]"),
N_("Manipulate PCI devices."), options);
}
diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c
index 3a0e0e0..e3347ee 100644
--- a/grub-core/commands/test.c
+++ b/grub-core/commands/test.c
@@ -38,114 +38,125 @@ grub_strtosl (char *arg, char **end, int base)
return grub_strtoul (arg, end, base);
}
-/* Parse a test expression starting from *argn. */
-static int
-test_parse (char **args, int *argn, int argc)
+/* Context for test_parse. */
+struct test_parse_ctx
{
- int ret = 0, discard = 0, invert = 0;
+ int ret, discard, invert;
int file_exists;
struct grub_dirhook_info file_info;
+ char *filename;
+};
+
+/* Take care of discarding and inverting. */
+static void
+update_val (int val, struct test_parse_ctx *ctx)
+{
+ if (! ctx->discard)
+ ctx->ret = ctx->invert ? ! val : val;
+ ctx->invert = ctx->discard = 0;
+}
+
+/* A hook for iterating directories. */
+static int
+find_file (const char *cur_filename, const struct grub_dirhook_info *info,
+ void *data)
+{
+ struct test_parse_ctx *ctx = data;
+
+ if ((info->case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename)
+ : grub_strcmp (cur_filename, ctx->filename)) == 0)
+ {
+ ctx->file_info = *info;
+ ctx->file_exists = 1;
+ return 1;
+ }
+ return 0;
+}
+
+/* Check if file exists and fetch its information. */
+static void
+get_fileinfo (char *path, struct test_parse_ctx *ctx)
+{
+ char *pathname;
+ char *device_name;
+ grub_fs_t fs;
+ grub_device_t dev;
+
+ ctx->file_exists = 0;
+ device_name = grub_file_get_device_name (path);
+ dev = grub_device_open (device_name);
+ if (! dev)
+ {
+ grub_free (device_name);
+ return;
+ }
- auto void update_val (int val);
- auto void get_fileinfo (char *pathname);
-
- /* Take care of discarding and inverting. */
- void update_val (int val)
- {
- if (! discard)
- ret = invert ? ! val : val;
- invert = discard = 0;
- }
-
- /* Check if file exists and fetch its information. */
- void get_fileinfo (char *path)
- {
- char *filename, *pathname;
- char *device_name;
- grub_fs_t fs;
- grub_device_t dev;
-
- /* A hook for iterating directories. */
- auto int find_file (const char *cur_filename,
- const struct grub_dirhook_info *info);
- int find_file (const char *cur_filename,
- const struct grub_dirhook_info *info)
+ fs = grub_fs_probe (dev);
+ if (! fs)
{
- if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename)
- : grub_strcmp (cur_filename, filename)) == 0)
+ grub_free (device_name);
+ grub_device_close (dev);
+ return;
+ }
+
+ pathname = grub_strchr (path, ')');
+ if (! pathname)
+ pathname = path;
+ else
+ pathname++;
+
+ /* Remove trailing '/'. */
+ while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
+ pathname[grub_strlen (pathname) - 1] = 0;
+
+ /* Split into path and filename. */
+ ctx->filename = grub_strrchr (pathname, '/');
+ if (! ctx->filename)
+ {
+ path = grub_strdup ("/");
+ ctx->filename = pathname;
+ }
+ else
+ {
+ ctx->filename++;
+ path = grub_strdup (pathname);
+ path[ctx->filename - pathname] = 0;
+ }
+
+ /* It's the whole device. */
+ if (! *pathname)
+ {
+ ctx->file_exists = 1;
+ grub_memset (&ctx->file_info, 0, sizeof (ctx->file_info));
+ /* Root is always a directory. */
+ ctx->file_info.dir = 1;
+
+ /* Fetch writing time. */
+ ctx->file_info.mtimeset = 0;
+ if (fs->mtime)
{
- file_info = *info;
- file_exists = 1;
- return 1;
+ if (! fs->mtime (dev, &ctx->file_info.mtime))
+ ctx->file_info.mtimeset = 1;
+ grub_errno = GRUB_ERR_NONE;
}
- return 0;
}
+ else
+ (fs->dir) (dev, path, find_file, ctx);
+
+ grub_device_close (dev);
+ grub_free (path);
+ grub_free (device_name);
+}
- file_exists = 0;
- device_name = grub_file_get_device_name (path);
- dev = grub_device_open (device_name);
- if (! dev)
- {
- grub_free (device_name);
- return;
- }
-
- fs = grub_fs_probe (dev);
- if (! fs)
- {
- grub_free (device_name);
- grub_device_close (dev);
- return;
- }
-
- pathname = grub_strchr (path, ')');
- if (! pathname)
- pathname = path;
- else
- pathname++;
-
- /* Remove trailing '/'. */
- while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
- pathname[grub_strlen (pathname) - 1] = 0;
-
- /* Split into path and filename. */
- filename = grub_strrchr (pathname, '/');
- if (! filename)
- {
- path = grub_strdup ("/");
- filename = pathname;
- }
- else
- {
- filename++;
- path = grub_strdup (pathname);
- path[filename - pathname] = 0;
- }
-
- /* It's the whole device. */
- if (! *pathname)
- {
- file_exists = 1;
- grub_memset (&file_info, 0, sizeof (file_info));
- /* Root is always a directory. */
- file_info.dir = 1;
-
- /* Fetch writing time. */
- file_info.mtimeset = 0;
- if (fs->mtime)
- {
- if (! fs->mtime (dev, &file_info.mtime))
- file_info.mtimeset = 1;
- grub_errno = GRUB_ERR_NONE;
- }
- }
- else
- (fs->dir) (dev, path, find_file);
-
- grub_device_close (dev);
- grub_free (path);
- grub_free (device_name);
- }
+/* Parse a test expression starting from *argn. */
+static int
+test_parse (char **args, int *argn, int argc)
+{
+ struct test_parse_ctx ctx = {
+ .ret = 0,
+ .discard = 0,
+ .invert = 0
+ };
/* Here we have the real parsing. */
while (*argn < argc)
@@ -157,14 +168,16 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn + 1], "=") == 0
|| grub_strcmp (args[*argn + 1], "==") == 0)
{
- update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0);
+ update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0,
+ &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "!=") == 0)
{
- update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0);
+ update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0,
+ &ctx);
(*argn) += 3;
continue;
}
@@ -172,28 +185,32 @@ test_parse (char **args, int *argn, int argc)
/* GRUB extension: lexicographical sorting. */
if (grub_strcmp (args[*argn + 1], "<") == 0)
{
- update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0);
+ update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0,
+ &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "<=") == 0)
{
- update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0);
+ update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0,
+ &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], ">") == 0)
{
- update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0);
+ update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0,
+ &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], ">=") == 0)
{
- update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0);
+ update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0,
+ &ctx);
(*argn) += 3;
continue;
}
@@ -202,7 +219,7 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn + 1], "-eq") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
- == grub_strtosl (args[*argn + 2], 0, 0));
+ == grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
@@ -210,7 +227,7 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn + 1], "-ge") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
- >= grub_strtosl (args[*argn + 2], 0, 0));
+ >= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
@@ -218,7 +235,7 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn + 1], "-gt") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
- > grub_strtosl (args[*argn + 2], 0, 0));
+ > grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
@@ -226,7 +243,7 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn + 1], "-le") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
- <= grub_strtosl (args[*argn + 2], 0, 0));
+ <= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
@@ -234,7 +251,7 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn + 1], "-lt") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
- < grub_strtosl (args[*argn + 2], 0, 0));
+ < grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
@@ -242,7 +259,7 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn + 1], "-ne") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
- != grub_strtosl (args[*argn + 2], 0, 0));
+ != grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
@@ -265,10 +282,10 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn + 1], "-pgt") == 0)
update_val (grub_strtoul (args[*argn] + i, 0, 0)
- > grub_strtoul (args[*argn + 2] + i, 0, 0));
+ > grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx);
else
update_val (grub_strtoul (args[*argn] + i, 0, 0)
- < grub_strtoul (args[*argn + 2] + i, 0, 0));
+ < grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx);
(*argn) += 3;
continue;
}
@@ -283,22 +300,24 @@ test_parse (char **args, int *argn, int argc)
int bias = 0;
/* Fetch fileinfo. */
- get_fileinfo (args[*argn]);
- file1 = file_info;
- file1exists = file_exists;
- get_fileinfo (args[*argn + 2]);
+ get_fileinfo (args[*argn], &ctx);
+ file1 = ctx.file_info;
+ file1exists = ctx.file_exists;
+ get_fileinfo (args[*argn + 2], &ctx);
if (args[*argn + 1][3])
bias = grub_strtosl (args[*argn + 1] + 3, 0, 0);
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0)
- update_val ((file1exists && ! file_exists)
- || (file1.mtimeset && file_info.mtimeset
- && file1.mtime + bias > file_info.mtime));
+ update_val ((file1exists && ! ctx.file_exists)
+ || (file1.mtimeset && ctx.file_info.mtimeset
+ && file1.mtime + bias > ctx.file_info.mtime),
+ &ctx);
else
- update_val ((! file1exists && file_exists)
- || (file1.mtimeset && file_info.mtimeset
- && file1.mtime + bias < file_info.mtime));
+ update_val ((! file1exists && ctx.file_exists)
+ || (file1.mtimeset && ctx.file_info.mtimeset
+ && file1.mtime + bias < ctx.file_info.mtime),
+ &ctx);
(*argn) += 3;
continue;
}
@@ -310,27 +329,27 @@ test_parse (char **args, int *argn, int argc)
/* File tests. */
if (grub_strcmp (args[*argn], "-d") == 0)
{
- get_fileinfo (args[*argn + 1]);
- update_val (file_exists && file_info.dir);
+ get_fileinfo (args[*argn + 1], &ctx);
+ update_val (ctx.file_exists && ctx.file_info.dir, &ctx);
(*argn) += 2;
- return ret;
+ return ctx.ret;
}
if (grub_strcmp (args[*argn], "-e") == 0)
{
- get_fileinfo (args[*argn + 1]);
- update_val (file_exists);
+ get_fileinfo (args[*argn + 1], &ctx);
+ update_val (ctx.file_exists, &ctx);
(*argn) += 2;
- return ret;
+ return ctx.ret;
}
if (grub_strcmp (args[*argn], "-f") == 0)
{
- get_fileinfo (args[*argn + 1]);
+ get_fileinfo (args[*argn + 1], &ctx);
/* FIXME: check for other types. */
- update_val (file_exists && ! file_info.dir);
+ update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx);
(*argn) += 2;
- return ret;
+ return ctx.ret;
}
if (grub_strcmp (args[*argn], "-s") == 0)
@@ -338,25 +357,25 @@ test_parse (char **args, int *argn, int argc)
grub_file_t file;
grub_file_filter_disable_compression ();
file = grub_file_open (args[*argn + 1]);
- update_val (file && (grub_file_size (file) != 0));
+ update_val (file && (grub_file_size (file) != 0), &ctx);
if (file)
grub_file_close (file);
grub_errno = GRUB_ERR_NONE;
(*argn) += 2;
- return ret;
+ return ctx.ret;
}
/* String tests. */
if (grub_strcmp (args[*argn], "-n") == 0)
{
- update_val (args[*argn + 1][0]);
+ update_val (args[*argn + 1][0], &ctx);
(*argn) += 2;
continue;
}
if (grub_strcmp (args[*argn], "-z") == 0)
{
- update_val (! args[*argn + 1][0]);
+ update_val (! args[*argn + 1][0], &ctx);
(*argn) += 2;
continue;
}
@@ -368,42 +387,42 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn], ")") == 0)
{
(*argn)++;
- return ret;
+ return ctx.ret;
}
/* Recursively invoke if parenthesis. */
if (grub_strcmp (args[*argn], "(") == 0)
{
(*argn)++;
- update_val (test_parse (args, argn, argc));
+ update_val (test_parse (args, argn, argc), &ctx);
continue;
}
if (grub_strcmp (args[*argn], "!") == 0)
{
- invert = ! invert;
+ ctx.invert = ! ctx.invert;
(*argn)++;
continue;
}
if (grub_strcmp (args[*argn], "-a") == 0)
{
/* If current value is 0 second value is to be discarded. */
- discard = ! ret;
+ ctx.discard = ! ctx.ret;
(*argn)++;
continue;
}
if (grub_strcmp (args[*argn], "-o") == 0)
{
/* If current value is 1 second value is to be discarded. */
- discard = ret;
+ ctx.discard = ctx.ret;
(*argn)++;
continue;
}
/* No test found. Interpret if as just a string. */
- update_val (args[*argn][0]);
+ update_val (args[*argn][0], &ctx);
(*argn)++;
}
- return ret;
+ return ctx.ret;
}
static grub_err_t
diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c
index 7247590..af35b8c 100644
--- a/grub-core/commands/usbtest.c
+++ b/grub-core/commands/usbtest.c
@@ -129,7 +129,7 @@ usb_print_str (const char *description, grub_usb_device_t dev, int idx)
}
static int
-usb_iterate (grub_usb_device_t dev)
+usb_iterate (grub_usb_device_t dev, void *data __attribute__ ((unused)))
{
struct grub_usb_desc_device *descdev;
int i;
@@ -199,7 +199,7 @@ grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)),
grub_usb_poll_devices ();
grub_printf ("USB devices:\n\n");
- grub_usb_iterate (usb_iterate);
+ grub_usb_iterate (usb_iterate, NULL);
return 0;
}
diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c
new file mode 100644
index 0000000..d399d0f
--- /dev/null
+++ b/grub-core/commands/verify.c
@@ -0,0 +1,787 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/command.h>
+#include <grub/crypto.h>
+#include <grub/i18n.h>
+#include <grub/gcrypt/gcrypt.h>
+#include <grub/pubkey.h>
+#include <grub/env.h>
+#include <grub/kernel.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_err_t
+read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len)
+{
+ grub_uint8_t type;
+ grub_uint8_t l;
+ grub_uint16_t l16;
+ grub_uint32_t l32;
+
+ /* New format. */
+ switch (grub_file_read (sig, &type, sizeof (type)))
+ {
+ case 1:
+ break;
+ case 0:
+ {
+ *out_type = 0xff;
+ return 0;
+ }
+ default:
+ if (grub_errno)
+ return grub_errno;
+ /* TRANSLATORS: it's about GNUPG signatures. */
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ }
+
+ if (type == 0)
+ {
+ *out_type = 0xfe;
+ return 0;
+ }
+
+ if (!(type & 0x80))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ if (type & 0x40)
+ {
+ *out_type = (type & 0x3f);
+ if (grub_file_read (sig, &l, sizeof (l)) != 1)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ if (l < 192)
+ {
+ *len = l;
+ return 0;
+ }
+ if (l < 224)
+ {
+ *len = (l - 192) << 8;
+ if (grub_file_read (sig, &l, sizeof (l)) != 1)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ *len |= l;
+ return 0;
+ }
+ if (l == 255)
+ {
+ if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ *len = grub_be_to_cpu32 (l32);
+ return 0;
+ }
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ }
+ *out_type = ((type >> 2) & 0xf);
+ switch (type & 0x3)
+ {
+ case 0:
+ if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ *len = l;
+ return 0;
+ case 1:
+ if (grub_file_read (sig, &l16, sizeof (l16)) != sizeof (l16))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ *len = grub_be_to_cpu16 (l16);
+ return 0;
+ case 2:
+ if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ *len = grub_be_to_cpu32 (l32);
+ return 0;
+ }
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+}
+
+struct signature_v4_header
+{
+ grub_uint8_t type;
+ grub_uint8_t pkeyalgo;
+ grub_uint8_t hash;
+ grub_uint16_t hashed_sub;
+} __attribute__ ((packed));
+
+const char *hashes[] = {
+ "md5", "sha1", "ripemd160",
+ [0x0a] = "sha512"
+};
+
+struct
+{
+ const char *name;
+ grub_size_t nmpisig;
+ grub_size_t nmpipub;
+} pkalgos[] =
+ {
+ [1] = { "rsa", 1, 2 },
+ [3] = { "rsa", 1, 2 },
+ [17] = { "dsa", 2, 4 },
+ };
+
+struct grub_public_key
+{
+ struct grub_public_key *next;
+ struct grub_public_subkey *subkeys;
+};
+
+struct grub_public_subkey
+{
+ struct grub_public_subkey *next;
+ grub_uint8_t type;
+ grub_uint32_t fingerprint[5];
+ gcry_mpi_t mpis[10];
+};
+
+static void
+free_pk (struct grub_public_key *pk)
+{
+ struct grub_public_subkey *nsk, *sk;
+ for (sk = pk->subkeys; sk; sk = nsk)
+ {
+ nsk = sk->next;
+ grub_free (sk);
+ }
+ grub_free (pk);
+}
+
+struct grub_public_key *
+grub_load_public_key (grub_file_t f)
+{
+ grub_err_t err;
+ struct grub_public_key *ret;
+ struct grub_public_subkey **last = 0;
+
+ ret = grub_zalloc (sizeof (*ret));
+ if (!ret)
+ return NULL;
+
+ last = &ret->subkeys;
+
+ while (1)
+ {
+ grub_uint8_t type;
+ grub_size_t len;
+ grub_uint8_t v, pk;
+ grub_uint32_t creation_time;
+ grub_off_t pend;
+ struct grub_public_subkey *sk;
+ grub_size_t i;
+ grub_uint16_t len_be;
+ GRUB_PROPERLY_ALIGNED_ARRAY (fingerprint_context, GRUB_MD_SHA1->contextsize);
+
+ err = read_packet_header (f, &type, &len);
+
+ if (err)
+ goto fail;
+ if (type == 0xfe)
+ continue;
+ if (type == 0xff)
+ return ret;
+
+ grub_dprintf ("crypt", "len = %x\n", (int) len);
+
+ pend = grub_file_tell (f) + len;
+ if (type != 6 && type != 14
+ && type != 5 && type != 7)
+ {
+ grub_file_seek (f, pend);
+ continue;
+ }
+
+ if (grub_file_read (f, &v, sizeof (v)) != sizeof (v))
+ {
+ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ goto fail;
+ }
+
+ grub_dprintf ("crypt", "v = %x\n", v);
+
+ if (v != 4)
+ {
+ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ goto fail;
+ }
+ if (grub_file_read (f, &creation_time, sizeof (creation_time)) != sizeof (creation_time))
+ {
+ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ goto fail;
+ }
+
+ grub_dprintf ("crypt", "time = %x\n", creation_time);
+
+ if (grub_file_read (f, &pk, sizeof (pk)) != sizeof (pk))
+ {
+ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ goto fail;
+ }
+
+ grub_dprintf ("crypt", "pk = %x\n", pk);
+
+ if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
+ {
+ grub_file_seek (f, pend);
+ continue;
+ }
+
+ sk = grub_zalloc (sizeof (struct grub_public_subkey));
+ if (!sk)
+ goto fail;
+
+ grub_memset (fingerprint_context, 0, sizeof (fingerprint_context));
+ GRUB_MD_SHA1->init (fingerprint_context);
+ GRUB_MD_SHA1->write (fingerprint_context, "\x99", 1);
+ len_be = grub_cpu_to_be16 (len);
+ GRUB_MD_SHA1->write (fingerprint_context, &len_be, sizeof (len_be));
+ GRUB_MD_SHA1->write (fingerprint_context, &v, sizeof (v));
+ GRUB_MD_SHA1->write (fingerprint_context, &creation_time, sizeof (creation_time));
+ GRUB_MD_SHA1->write (fingerprint_context, &pk, sizeof (pk));
+
+ for (i = 0; i < pkalgos[pk].nmpipub; i++)
+ {
+ grub_uint16_t l;
+ grub_size_t lb;
+ grub_uint8_t buffer[4096];
+ if (grub_file_read (f, &l, sizeof (l)) != sizeof (l))
+ {
+ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ goto fail;
+ }
+
+ lb = (grub_be_to_cpu16 (l) + 7) / 8;
+ if (lb > sizeof (buffer) - sizeof (grub_uint16_t))
+ {
+ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ goto fail;
+ }
+ if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
+ {
+ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ goto fail;
+ }
+ grub_memcpy (buffer, &l, sizeof (l));
+
+ GRUB_MD_SHA1->write (fingerprint_context, buffer, lb + sizeof (grub_uint16_t));
+
+ if (gcry_mpi_scan (&sk->mpis[i], GCRYMPI_FMT_PGP,
+ buffer, lb + sizeof (grub_uint16_t), 0))
+ {
+ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ goto fail;
+ }
+ }
+
+ GRUB_MD_SHA1->final (fingerprint_context);
+
+ grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20);
+
+ *last = sk;
+ last = &sk->next;
+
+ grub_dprintf ("crypt", "actual pos: %x, expected: %x\n", (int)grub_file_tell (f), (int)pend);
+
+ grub_file_seek (f, pend);
+ }
+ fail:
+ free_pk (ret);
+ return NULL;
+}
+
+struct grub_public_key *grub_pk_trusted;
+
+struct grub_public_subkey *
+grub_crypto_pk_locate_subkey (grub_uint64_t keyid, struct grub_public_key *pkey)
+{
+ struct grub_public_subkey *sk;
+ for (sk = pkey->subkeys; sk; sk = sk->next)
+ if (grub_memcmp (sk->fingerprint + 3, &keyid, 8) == 0)
+ return sk;
+ return 0;
+}
+
+struct grub_public_subkey *
+grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid)
+{
+ struct grub_public_key *pkey;
+ struct grub_public_subkey *sk;
+ for (pkey = grub_pk_trusted; pkey; pkey = pkey->next)
+ {
+ sk = grub_crypto_pk_locate_subkey (keyid, pkey);
+ if (sk)
+ return sk;
+ }
+ return 0;
+}
+
+grub_err_t
+grub_verify_signature (grub_file_t f, grub_file_t sig,
+ struct grub_public_key *pkey)
+{
+ grub_size_t len;
+ grub_uint8_t v;
+ grub_uint8_t h;
+ grub_uint8_t t;
+ grub_uint8_t pk;
+ const gcry_md_spec_t *hash;
+ struct signature_v4_header v4;
+ grub_err_t err;
+ grub_size_t i;
+ gcry_mpi_t mpis[10];
+ grub_uint8_t type;
+
+ err = read_packet_header (sig, &type, &len);
+ if (err)
+ return err;
+
+ if (type != 0x2)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+
+ if (grub_file_read (sig, &v, sizeof (v)) != sizeof (v))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+
+ if (v != 4)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+
+ if (grub_file_read (sig, &v4, sizeof (v4)) != sizeof (v4))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+
+ h = v4.hash;
+ t = v4.type;
+ pk = v4.pkeyalgo;
+
+ if (t != 0)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+
+ if (h >= ARRAY_SIZE (hashes) || hashes[h] == NULL)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, "unknown hash");
+
+ if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+
+ hash = grub_crypto_lookup_md_by_name (hashes[h]);
+ if (!hash)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]);
+
+ grub_dprintf ("crypt", "alive\n");
+
+ {
+ GRUB_PROPERLY_ALIGNED_ARRAY (context, hash->contextsize);
+ unsigned char *hval;
+ grub_ssize_t rem = grub_be_to_cpu16 (v4.hashed_sub);
+ grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
+ grub_uint8_t s;
+ grub_uint16_t unhashed_sub;
+ grub_ssize_t r;
+ grub_uint8_t hash_start[2];
+ gcry_mpi_t hmpi;
+ grub_uint64_t keyid = 0;
+ struct grub_public_subkey *sk;
+
+ grub_memset (context, 0, sizeof (context));
+ hash->init (context);
+ while (1)
+ {
+ grub_uint8_t readbuf[4096];
+ r = grub_file_read (f, readbuf, sizeof (readbuf));
+ if (r < 0)
+ return grub_errno;
+ if (r == 0)
+ break;
+ hash->write (context, readbuf, r);
+ }
+
+ hash->write (context, &v, sizeof (v));
+ hash->write (context, &v4, sizeof (v4));
+ while (rem)
+ {
+ grub_uint8_t readbuf[4096];
+ r = grub_file_read (sig, readbuf, rem < (grub_ssize_t) sizeof (readbuf) ? rem : (grub_ssize_t) sizeof (readbuf));
+ if (r < 0)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ if (r == 0)
+ break;
+ hash->write (context, readbuf, r);
+ rem -= r;
+ }
+ hash->write (context, &v, sizeof (v));
+ s = 0xff;
+ hash->write (context, &s, sizeof (s));
+ hash->write (context, &headlen, sizeof (headlen));
+ r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub));
+ if (r != sizeof (unhashed_sub))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ {
+ grub_uint8_t readbuf[4096];
+ grub_uint8_t *ptr;
+ grub_uint32_t l;
+ rem = grub_be_to_cpu16 (unhashed_sub);
+ if (rem > (int) sizeof (readbuf))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ r = grub_file_read (sig, readbuf, rem);
+ if (r != rem)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ for (ptr = readbuf; ptr < readbuf + rem; ptr += l)
+ {
+ if (*ptr < 192)
+ l = *ptr++;
+ else if (*ptr < 255)
+ {
+ if (ptr + 1 >= readbuf + rem)
+ break;
+ l = (((ptr[0] & ~192) << 8) | ptr[1]) + 192;
+ ptr += 2;
+ }
+ else
+ {
+ if (ptr + 5 >= readbuf + rem)
+ break;
+ l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1));
+ ptr += 5;
+ }
+ if (*ptr == 0x10 && l >= 8)
+ keyid = grub_get_unaligned64 (ptr + 1);
+ }
+ }
+
+ hash->final (context);
+
+ grub_dprintf ("crypt", "alive\n");
+
+ hval = hash->read (context);
+
+ if (grub_file_read (sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+
+ grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig));
+
+ for (i = 0; i < pkalgos[pk].nmpisig; i++)
+ {
+ grub_uint16_t l;
+ grub_size_t lb;
+ grub_uint8_t buffer[4096];
+ grub_dprintf ("crypt", "alive\n");
+ if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ grub_dprintf ("crypt", "alive\n");
+ lb = (grub_be_to_cpu16 (l) + 7) / 8;
+ grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
+ if (lb > sizeof (buffer) - sizeof (grub_uint16_t))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ grub_dprintf ("crypt", "alive\n");
+ if (grub_file_read (sig, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ grub_dprintf ("crypt", "alive\n");
+ grub_memcpy (buffer, &l, sizeof (l));
+ grub_dprintf ("crypt", "alive\n");
+
+ if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
+ buffer, lb + sizeof (grub_uint16_t), 0))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ grub_dprintf ("crypt", "alive\n");
+ }
+
+ if (pkey)
+ sk = grub_crypto_pk_locate_subkey (keyid, pkey);
+ else
+ sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
+ if (!sk)
+ /* TRANSLATORS: %08x is 32-bit key id. */
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), keyid);
+
+ int nbits = gcry_mpi_get_nbits (sk->mpis[1]);
+ grub_dprintf ("crypt", "must be %d bits got %d bits\n", (int)nbits, (int)(8 * hash->mdlen));
+
+ if (gcry_mpi_scan (&hmpi, GCRYMPI_FMT_USG, hval, nbits / 8 < (int) hash->mdlen ? nbits / 8 : (int) hash->mdlen, 0))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ if (!grub_crypto_pk_dsa)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"), "gcry_dsa");
+ if (grub_crypto_pk_dsa->verify (0, hmpi, mpis, sk->mpis, 0, 0))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_trust (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_file_t pkf;
+ struct grub_public_key *pk = NULL;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
+
+ grub_file_filter_disable_all ();
+ pkf = grub_file_open (args[0]);
+ if (!pkf)
+ return grub_errno;
+ pk = grub_load_public_key (pkf);
+ if (!pk)
+ {
+ grub_file_close (pkf);
+ return grub_errno;
+ }
+ grub_file_close (pkf);
+
+ pk->next = grub_pk_trusted;
+ grub_pk_trusted = pk;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_list (grub_command_t cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ struct grub_public_key *pk = NULL;
+ struct grub_public_subkey *sk = NULL;
+
+ for (pk = grub_pk_trusted; pk; pk = pk->next)
+ for (sk = pk->subkeys; sk; sk = sk->next)
+ {
+ unsigned i;
+ for (i = 0; i < 20; i += 2)
+ grub_printf ("%02x%02x ", ((grub_uint8_t *) sk->fingerprint)[i],
+ ((grub_uint8_t *) sk->fingerprint)[i + 1]);
+ grub_printf ("\n");
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_uint32_t keyid, keyid_be;
+ struct grub_public_key **pkey;
+ struct grub_public_subkey *sk;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
+ keyid = grub_strtoull (args[0], 0, 16);
+ if (grub_errno)
+ return grub_errno;
+ keyid_be = grub_cpu_to_be32 (keyid);
+
+ for (pkey = &grub_pk_trusted; *pkey; pkey = &((*pkey)->next))
+ {
+ struct grub_public_key *next;
+ for (sk = (*pkey)->subkeys; sk; sk = sk->next)
+ if (grub_memcmp (sk->fingerprint + 4, &keyid_be, 4) == 0)
+ break;
+ if (!sk)
+ continue;
+ next = (*pkey)->next;
+ free_pk (*pkey);
+ *pkey = next;
+ return GRUB_ERR_NONE;
+ }
+ /* TRANSLATORS: %08x is 32-bit key id. */
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), keyid);
+}
+
+static grub_err_t
+grub_cmd_verify_signature (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_file_t f, sig;
+ grub_err_t err;
+ struct grub_public_key *pk = NULL;
+
+ grub_dprintf ("crypt", "alive\n");
+
+ if (argc < 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
+
+ grub_dprintf ("crypt", "alive\n");
+
+ if (argc > 2)
+ {
+ grub_file_t pkf;
+ grub_file_filter_disable_all ();
+ pkf = grub_file_open (args[2]);
+ if (!pkf)
+ return grub_errno;
+ pk = grub_load_public_key (pkf);
+ if (!pk)
+ {
+ grub_file_close (pkf);
+ return grub_errno;
+ }
+ grub_file_close (pkf);
+ }
+
+ grub_file_filter_disable_all ();
+ f = grub_file_open (args[0]);
+ if (!f)
+ return grub_errno;
+
+ grub_file_filter_disable_all ();
+ sig = grub_file_open (args[1]);
+ if (!sig)
+ {
+ grub_file_close (f);
+ return grub_errno;
+ }
+
+ err = grub_verify_signature (f, sig, pk);
+ grub_file_close (f);
+ grub_file_close (sig);
+ return err;
+}
+
+static int sec = 0;
+
+static grub_file_t
+grub_pubkey_open (grub_file_t io, const char *filename)
+{
+ grub_file_t sig;
+ char *fsuf, *ptr;
+ grub_err_t err;
+ grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX];
+
+ if (!sec)
+ return io;
+ fsuf = grub_malloc (grub_strlen (filename) + sizeof (".sig"));
+ if (!fsuf)
+ return NULL;
+ ptr = grub_stpcpy (fsuf, filename);
+ grub_memcpy (ptr, ".sig", sizeof (".sig"));
+
+ grub_memcpy (curfilt, grub_file_filters_enabled,
+ sizeof (curfilt));
+ grub_file_filter_disable_all ();
+ sig = grub_file_open (fsuf);
+ grub_memcpy (grub_file_filters_enabled, curfilt,
+ sizeof (curfilt));
+ grub_free (fsuf);
+ if (!sig)
+ return NULL;
+
+ err = grub_verify_signature (io, sig, NULL);
+ grub_file_close (sig);
+ if (err)
+ return NULL;
+ grub_file_seek (io, 0);
+ return io;
+}
+
+static char *
+grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)),
+ const char *val)
+{
+ sec = (*val == '1') || (*val == 'e');
+ return grub_strdup (sec ? "enforce" : "no");
+}
+
+static grub_ssize_t
+pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
+{
+ grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
+ return len;
+}
+
+
+/* Filesystem descriptor. */
+struct grub_fs pseudo_fs =
+ {
+ .name = "pseudo",
+ .read = pseudo_read
+};
+
+struct gcry_pk_spec *grub_crypto_pk_dsa;
+struct gcry_pk_spec *grub_crypto_pk_ecdsa;
+struct gcry_pk_spec *grub_crypto_pk_rsa;
+
+static grub_command_t cmd, cmd_trust, cmd_distrust, cmd_list;
+
+GRUB_MOD_INIT(verify)
+{
+ const char *val;
+ struct grub_module_header *header;
+
+ val = grub_env_get ("check_signatures");
+ if (val && (val[0] == '1' || val[0] == 'e'))
+ sec = 1;
+ else
+ sec = 0;
+
+ grub_file_filter_register (GRUB_FILE_FILTER_PUBKEY, grub_pubkey_open);
+
+ grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec);
+ grub_env_export ("check_signatures");
+
+ grub_pk_trusted = 0;
+ FOR_MODULES (header)
+ {
+ struct grub_file pseudo_file;
+ struct grub_public_key *pk = NULL;
+
+ grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
+
+ /* Not an ELF module, skip. */
+ if (header->type != OBJ_TYPE_PUBKEY)
+ continue;
+
+ pseudo_file.fs = &pseudo_fs;
+ pseudo_file.size = (header->size - sizeof (struct grub_module_header));
+ pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
+
+ pk = grub_load_public_key (&pseudo_file);
+ if (!pk)
+ grub_fatal ("error loading initial key: %s\n", grub_errmsg);
+
+ pk->next = grub_pk_trusted;
+ grub_pk_trusted = pk;
+ }
+
+ if (!val)
+ grub_env_set ("check_signatures", grub_pk_trusted ? "enforce" : "no");
+
+ cmd = grub_register_command ("verify_detached", grub_cmd_verify_signature,
+ N_("FILE SIGNATURE_FILE [PUBKEY_FILE]"),
+ N_("Verify detached signature."));
+ cmd_trust = grub_register_command ("trust", grub_cmd_trust,
+ N_("PUBKEY_FILE"),
+ N_("Add PKFILE to trusted keys."));
+ cmd_list = grub_register_command ("list_trusted", grub_cmd_list,
+ 0,
+ N_("List trusted keys."));
+ cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust,
+ N_("PUBKEY_ID"),
+ N_("Remove KEYID from trusted keys."));
+}
+
+GRUB_MOD_FINI(verify)
+{
+ grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY);
+ grub_unregister_command (cmd);
+ grub_unregister_command (cmd_trust);
+ grub_unregister_command (cmd_list);
+ grub_unregister_command (cmd_distrust);
+}
diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
index 2b73d9a..2807f80 100644
--- a/grub-core/commands/wildcard.c
+++ b/grub-core/commands/wildcard.c
@@ -210,120 +210,144 @@ split_path (const char *str, const char **noregexop, const char **regexop)
*noregexop = split;
}
-static char **
-match_devices (const regex_t *regexp, int noparts)
+/* Context for match_devices. */
+struct match_devices_ctx
{
- int i;
+ const regex_t *regexp;
+ int noparts;
int ndev;
char **devs;
+};
- auto int match (const char *name);
- int match (const char *name)
- {
- char **t;
- char *buffer;
+/* Helper for match_devices. */
+static int
+match_devices_iter (const char *name, void *data)
+{
+ struct match_devices_ctx *ctx = data;
+ char **t;
+ char *buffer;
- /* skip partitions if asked to. */
- if (noparts && grub_strchr(name, ','))
- return 0;
+ /* skip partitions if asked to. */
+ if (ctx->noparts && grub_strchr (name, ','))
+ return 0;
- buffer = grub_xasprintf ("(%s)", name);
- if (! buffer)
- return 1;
+ buffer = grub_xasprintf ("(%s)", name);
+ if (! buffer)
+ return 1;
- grub_dprintf ("expand", "matching: %s\n", buffer);
- if (regexec (regexp, buffer, 0, 0, 0))
- {
- grub_dprintf ("expand", "not matched\n");
- grub_free (buffer);
- return 0;
- }
+ grub_dprintf ("expand", "matching: %s\n", buffer);
+ if (regexec (ctx->regexp, buffer, 0, 0, 0))
+ {
+ grub_dprintf ("expand", "not matched\n");
+ grub_free (buffer);
+ return 0;
+ }
- t = grub_realloc (devs, sizeof (char*) * (ndev + 2));
- if (! t)
- return 1;
+ t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
+ if (! t)
+ return 1;
- devs = t;
- devs[ndev++] = buffer;
- devs[ndev] = 0;
- return 0;
- }
+ ctx->devs = t;
+ ctx->devs[ctx->ndev++] = buffer;
+ ctx->devs[ctx->ndev] = 0;
+ return 0;
+}
- ndev = 0;
- devs = 0;
+static char **
+match_devices (const regex_t *regexp, int noparts)
+{
+ struct match_devices_ctx ctx = {
+ .regexp = regexp,
+ .noparts = noparts,
+ .ndev = 0,
+ .devs = 0
+ };
+ int i;
- if (grub_device_iterate (match))
+ if (grub_device_iterate (match_devices_iter, &ctx))
goto fail;
- return devs;
+ return ctx.devs;
fail:
- for (i = 0; devs && devs[i]; i++)
- grub_free (devs[i]);
+ for (i = 0; ctx.devs && ctx.devs[i]; i++)
+ grub_free (ctx.devs[i]);
- grub_free (devs);
+ grub_free (ctx.devs);
return 0;
}
-static char **
-match_files (const char *prefix, const char *suffix, const char *end,
- const regex_t *regexp)
+/* Context for match_files. */
+struct match_files_ctx
{
- int i;
+ const regex_t *regexp;
char **files;
unsigned nfile;
char *dir;
- const char *path;
- char *device_name;
- grub_fs_t fs;
- grub_device_t dev;
+};
- auto int match (const char *name, const struct grub_dirhook_info *info);
- int match (const char *name, const struct grub_dirhook_info *info)
- {
- char **t;
- char *buffer;
+/* Helper for match_files. */
+static int
+match_files_iter (const char *name, const struct grub_dirhook_info *info,
+ void *data)
+{
+ struct match_files_ctx *ctx = data;
+ char **t;
+ char *buffer;
- /* skip . and .. names */
- if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
- return 0;
+ /* skip . and .. names */
+ if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
+ return 0;
- grub_dprintf ("expand", "matching: %s in %s\n", name, dir);
- if (regexec (regexp, name, 0, 0, 0))
- return 0;
+ grub_dprintf ("expand", "matching: %s in %s\n", name, ctx->dir);
+ if (regexec (ctx->regexp, name, 0, 0, 0))
+ return 0;
- grub_dprintf ("expand", "matched\n");
+ grub_dprintf ("expand", "matched\n");
- buffer = grub_xasprintf ("%s%s", dir, name);
- if (! buffer)
+ buffer = grub_xasprintf ("%s%s", ctx->dir, name);
+ if (! buffer)
+ return 1;
+
+ t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2));
+ if (! t)
+ {
+ grub_free (buffer);
return 1;
+ }
- t = grub_realloc (files, sizeof (char*) * (nfile + 2));
- if (! t)
- {
- grub_free (buffer);
- return 1;
- }
+ ctx->files = t;
+ ctx->files[ctx->nfile++] = buffer;
+ ctx->files[ctx->nfile] = 0;
+ return 0;
+}
- files = t;
- files[nfile++] = buffer;
- files[nfile] = 0;
- return 0;
- }
+static char **
+match_files (const char *prefix, const char *suffix, const char *end,
+ const regex_t *regexp)
+{
+ struct match_files_ctx ctx = {
+ .regexp = regexp,
+ .nfile = 0,
+ .files = 0
+ };
+ int i;
+ const char *path;
+ char *device_name;
+ grub_fs_t fs;
+ grub_device_t dev;
- nfile = 0;
- files = 0;
dev = 0;
device_name = 0;
grub_error_push ();
- dir = make_dir (prefix, suffix, end);
- if (! dir)
+ ctx.dir = make_dir (prefix, suffix, end);
+ if (! ctx.dir)
goto fail;
- device_name = grub_file_get_device_name (dir);
+ device_name = grub_file_get_device_name (ctx.dir);
dev = grub_device_open (device_name);
if (! dev)
goto fail;
@@ -332,33 +356,33 @@ match_files (const char *prefix, const char *suffix, const char *end,
if (! fs)
goto fail;
- if (dir[0] == '(')
+ if (ctx.dir[0] == '(')
{
- path = grub_strchr (dir, ')');
+ path = grub_strchr (ctx.dir, ')');
if (!path)
goto fail;
path++;
}
else
- path = dir;
+ path = ctx.dir;
- if (fs->dir (dev, path, match))
+ if (fs->dir (dev, path, match_files_iter, &ctx))
goto fail;
- grub_free (dir);
+ grub_free (ctx.dir);
grub_device_close (dev);
grub_free (device_name);
grub_error_pop ();
- return files;
+ return ctx.files;
fail:
- grub_free (dir);
+ grub_free (ctx.dir);
- for (i = 0; files && files[i]; i++)
- grub_free (files[i]);
+ for (i = 0; ctx.files && ctx.files[i]; i++)
+ grub_free (ctx.files[i]);
- grub_free (files);
+ grub_free (ctx.files);
if (dev)
grub_device_close (dev);
@@ -369,28 +393,42 @@ match_files (const char *prefix, const char *suffix, const char *end,
return 0;
}
+/* Context for check_file. */
+struct check_file_ctx
+{
+ const char *basename;
+ int found;
+};
+
+/* Helper for check_file. */
+static int
+check_file_iter (const char *name, const struct grub_dirhook_info *info,
+ void *data)
+{
+ struct check_file_ctx *ctx = data;
+
+ if (ctx->basename[0] == 0
+ || (info->case_insensitive ? grub_strcasecmp (name, ctx->basename) == 0
+ : grub_strcmp (name, ctx->basename) == 0))
+ {
+ ctx->found = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
static int
check_file (const char *dir, const char *basename)
{
+ struct check_file_ctx ctx = {
+ .basename = basename,
+ .found = 0
+ };
grub_fs_t fs;
grub_device_t dev;
- int found = 0;
const char *device_name, *path;
- auto int match (const char *name, const struct grub_dirhook_info *info);
- int match (const char *name, const struct grub_dirhook_info *info)
- {
- if (basename[0] == 0
- || (info->case_insensitive ? grub_strcasecmp (name, basename) == 0
- : grub_strcmp (name, basename) == 0))
- {
- found = 1;
- return 1;
- }
-
- return 0;
- }
-
device_name = grub_file_get_device_name (dir);
dev = grub_device_open (device_name);
if (! dev)
@@ -410,14 +448,14 @@ check_file (const char *dir, const char *basename)
else
path = dir;
- fs->dir (dev, path[0] ? path : "/", match);
+ fs->dir (dev, path[0] ? path : "/", check_file_iter, &ctx);
if (grub_errno == 0 && basename[0] == 0)
- found = 1;
+ ctx.found = 1;
fail:
grub_errno = 0;
- return found;
+ return ctx.found;
}
static void
diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c
index 4ab2d18..f9258fd 100644
--- a/grub-core/disk/ahci.c
+++ b/grub-core/disk/ahci.c
@@ -254,9 +254,10 @@ init_port (struct grub_ahci_device *dev)
return 1;
}
-static int NESTED_FUNC_ATTR
+static int
grub_ahci_pciinit (grub_pci_device_t dev,
- grub_pci_id_t pciid __attribute__ ((unused)))
+ grub_pci_id_t pciid __attribute__ ((unused)),
+ void *data __attribute__ ((unused)))
{
grub_pci_address_t addr;
grub_uint32_t class;
@@ -394,7 +395,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
static grub_err_t
grub_ahci_initialize (void)
{
- grub_pci_iterate (grub_ahci_pciinit);
+ grub_pci_iterate (grub_ahci_pciinit, NULL);
return grub_errno;
}
@@ -454,8 +455,8 @@ grub_ahci_restore_hw (void)
static int
-grub_ahci_iterate (int (*hook) (int id, int bus),
- grub_disk_pull_t pull)
+grub_ahci_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
struct grub_ahci_device *dev;
@@ -463,7 +464,7 @@ grub_ahci_iterate (int (*hook) (int id, int bus),
return 0;
FOR_LIST_ELEMENTS(dev, grub_ahci_devices)
- if (hook (GRUB_SCSI_SUBSYSTEM_AHCI, dev->num))
+ if (hook (GRUB_SCSI_SUBSYSTEM_AHCI, dev->num, hook_data))
return 1;
return 0;
diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c
index 10cbc87..5d12128 100644
--- a/grub-core/disk/arc/arcdisk.c
+++ b/grub-core/disk/arc/arcdisk.c
@@ -80,23 +80,37 @@ arcdisk_hash_add (char *devpath)
}
+/* Context for grub_arcdisk_iterate. */
+struct grub_arcdisk_iterate_ctx
+{
+ grub_disk_dev_iterate_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_arcdisk_iterate. */
static int
-grub_arcdisk_iterate (int (*hook_in) (const char *name),
+grub_arcdisk_iterate_iter (const char *name,
+ const struct grub_arc_component *comp, void *data)
+{
+ struct grub_arcdisk_iterate_ctx *ctx = data;
+
+ if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
+ || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
+ || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE))
+ return 0;
+ return ctx->hook (name, ctx->hook_data);
+}
+
+static int
+grub_arcdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
- auto int hook (const char *name, const struct grub_arc_component *comp);
- int hook (const char *name, const struct grub_arc_component *comp)
- {
- if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
- || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK
- || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE))
- return 0;
- return hook_in (name);
- }
+ struct grub_arcdisk_iterate_ctx ctx = { hook, hook_data };
+
if (pull != GRUB_DISK_PULL_NONE)
return 0;
- return grub_arc_iterate_devs (hook, 1);
+ return grub_arc_iterate_devs (grub_arcdisk_iterate_iter, &ctx, 1);
}
#define RAW_SUFFIX "partition(10)"
diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c
index c0d378c..c84d316 100644
--- a/grub-core/disk/ata.c
+++ b/grub-core/disk/ata.c
@@ -392,40 +392,50 @@ grub_ata_real_open (int id, int bus)
return NULL;
}
+/* Context for grub_ata_iterate. */
+struct grub_ata_iterate_ctx
+{
+ grub_disk_dev_iterate_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_ata_iterate. */
static int
-grub_ata_iterate (int (*hook_in) (const char *name),
- grub_disk_pull_t pull)
+grub_ata_iterate_iter (int id, int bus, void *data)
{
- auto int hook (int id, int bus);
- int hook (int id, int bus)
- {
- struct grub_ata *ata;
- int ret;
- char devname[40];
+ struct grub_ata_iterate_ctx *ctx = data;
+ struct grub_ata *ata;
+ int ret;
+ char devname[40];
- ata = grub_ata_real_open (id, bus);
+ ata = grub_ata_real_open (id, bus);
- if (!ata)
- {
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- if (ata->atapi)
- {
- grub_ata_real_close (ata);
- return 0;
- }
- grub_snprintf (devname, sizeof (devname),
- "%s%d", grub_scsi_names[id], bus);
- ret = hook_in (devname);
- grub_ata_real_close (ata);
- return ret;
- }
+ if (!ata)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (ata->atapi)
+ {
+ grub_ata_real_close (ata);
+ return 0;
+ }
+ grub_snprintf (devname, sizeof (devname),
+ "%s%d", grub_scsi_names[id], bus);
+ ret = ctx->hook (devname, ctx->hook_data);
+ grub_ata_real_close (ata);
+ return ret;
+}
+static int
+grub_ata_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
+{
+ struct grub_ata_iterate_ctx ctx = { hook, hook_data };
grub_ata_dev_t p;
for (p = grub_ata_dev_list; p; p = p->next)
- if (p->iterate && p->iterate (hook, pull))
+ if (p->iterate && p->iterate (grub_ata_iterate_iter, &ctx, pull))
return 1;
return 0;
}
@@ -561,37 +571,47 @@ grub_atapi_open (int id, int bus, struct grub_scsi *scsi)
return GRUB_ERR_NONE;
}
+/* Context for grub_atapi_iterate. */
+struct grub_atapi_iterate_ctx
+{
+ grub_scsi_dev_iterate_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_atapi_iterate. */
static int
-grub_atapi_iterate (int NESTED_FUNC_ATTR (*hook_in) (int id, int bus, int luns),
- grub_disk_pull_t pull)
+grub_atapi_iterate_iter (int id, int bus, void *data)
{
- auto int hook (int id, int bus);
- int hook (int id, int bus)
- {
- struct grub_ata *ata;
- int ret;
+ struct grub_atapi_iterate_ctx *ctx = data;
+ struct grub_ata *ata;
+ int ret;
- ata = grub_ata_real_open (id, bus);
+ ata = grub_ata_real_open (id, bus);
- if (!ata)
- {
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- if (!ata->atapi)
- {
- grub_ata_real_close (ata);
- return 0;
- }
- ret = hook_in (id, bus, 1);
- grub_ata_real_close (ata);
- return ret;
- }
+ if (!ata)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (!ata->atapi)
+ {
+ grub_ata_real_close (ata);
+ return 0;
+ }
+ ret = ctx->hook (id, bus, 1, ctx->hook_data);
+ grub_ata_real_close (ata);
+ return ret;
+}
+static int
+grub_atapi_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
+{
+ struct grub_atapi_iterate_ctx ctx = { hook, hook_data };
grub_ata_dev_t p;
for (p = grub_ata_dev_list; p; p = p->next)
- if (p->iterate && p->iterate (hook, pull))
+ if (p->iterate && p->iterate (grub_atapi_iterate_iter, &ctx, pull))
return 1;
return 0;
}
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 3de3b86..ce755c3 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -448,8 +448,8 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke
}
static int
-grub_cryptodisk_iterate (int (*hook) (const char *name),
- grub_disk_pull_t pull)
+grub_cryptodisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
grub_cryptodisk_t i;
@@ -460,7 +460,7 @@ grub_cryptodisk_iterate (int (*hook) (const char *name),
{
char buf[30];
grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
@@ -866,7 +866,8 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
#endif
static int
-grub_cryptodisk_scan_device (const char *name)
+grub_cryptodisk_scan_device (const char *name,
+ void *data __attribute__ ((unused)))
{
grub_err_t err;
grub_disk_t source;
@@ -908,7 +909,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
check_boot = state[2].set;
search_uuid = args[0];
- grub_device_iterate (&grub_cryptodisk_scan_device);
+ grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
search_uuid = NULL;
if (!have_it)
@@ -919,7 +920,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
{
search_uuid = NULL;
check_boot = state[2].set;
- grub_device_iterate (&grub_cryptodisk_scan_device);
+ grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
search_uuid = NULL;
return GRUB_ERR_NONE;
}
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
index ce4c706..2ff47e9 100644
--- a/grub-core/disk/diskfilter.c
+++ b/grub-core/disk/diskfilter.c
@@ -120,65 +120,68 @@ is_valid_diskfilter_name (const char *name)
|| grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0);
}
+/* Helper for scan_disk. */
static int
-scan_disk (const char *name, int accept_diskfilter)
+scan_disk_partition_iter (grub_disk_t disk, grub_partition_t p, void *data)
{
- auto int hook (grub_disk_t disk, grub_partition_t p);
- int hook (grub_disk_t disk, grub_partition_t p)
- {
- struct grub_diskfilter_vg *arr;
- grub_disk_addr_t start_sector;
- struct grub_diskfilter_pv_id id;
- grub_diskfilter_t diskfilter;
-
- grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n",
- name);
+ const char *name = data;
+ struct grub_diskfilter_vg *arr;
+ grub_disk_addr_t start_sector;
+ struct grub_diskfilter_pv_id id;
+ grub_diskfilter_t diskfilter;
+
+ grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n",
+ name);
#ifdef GRUB_UTIL
- grub_util_info ("Scanning for DISKFILTER devices on disk %s", name);
+ grub_util_info ("Scanning for DISKFILTER devices on disk %s", name);
#endif
- disk->partition = p;
-
- for (arr = array_list; arr != NULL; arr = arr->next)
- {
- struct grub_diskfilter_pv *m;
- for (m = arr->pvs; m; m = m->next)
- if (m->disk && m->disk->id == disk->id
- && m->disk->dev->id == disk->dev->id
- && m->part_start == grub_partition_get_start (disk->partition)
- && m->part_size == grub_disk_get_size (disk))
- return 0;
- }
+ disk->partition = p;
+
+ for (arr = array_list; arr != NULL; arr = arr->next)
+ {
+ struct grub_diskfilter_pv *m;
+ for (m = arr->pvs; m; m = m->next)
+ if (m->disk && m->disk->id == disk->id
+ && m->disk->dev->id == disk->dev->id
+ && m->part_start == grub_partition_get_start (disk->partition)
+ && m->part_size == grub_disk_get_size (disk))
+ return 0;
+ }
- for (diskfilter = grub_diskfilter_list; diskfilter; diskfilter = diskfilter->next)
- {
+ for (diskfilter = grub_diskfilter_list; diskfilter; diskfilter = diskfilter->next)
+ {
#ifdef GRUB_UTIL
- grub_util_info ("Scanning for %s devices on disk %s",
- diskfilter->name, name);
+ grub_util_info ("Scanning for %s devices on disk %s",
+ diskfilter->name, name);
#endif
- id.uuid = 0;
- id.uuidlen = 0;
- arr = diskfilter->detect (disk, &id, &start_sector);
- if (arr &&
- (! insert_array (disk, &id, arr, start_sector, diskfilter)))
- {
- if (id.uuidlen)
- grub_free (id.uuid);
- return 0;
- }
- if (arr && id.uuidlen)
+ id.uuid = 0;
+ id.uuidlen = 0;
+ arr = diskfilter->detect (disk, &id, &start_sector);
+ if (arr &&
+ (! insert_array (disk, &id, arr, start_sector, diskfilter)))
+ {
+ if (id.uuidlen)
grub_free (id.uuid);
-
- /* This error usually means it's not diskfilter, no need to display
- it. */
- if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
- grub_print_error ();
-
- grub_errno = GRUB_ERR_NONE;
+ return 0;
}
+ if (arr && id.uuidlen)
+ grub_free (id.uuid);
- return 0;
+ /* This error usually means it's not diskfilter, no need to display
+ it. */
+ if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
+ grub_print_error ();
+
+ grub_errno = GRUB_ERR_NONE;
}
+
+ return 0;
+}
+
+static int
+scan_disk (const char *name, int accept_diskfilter)
+{
grub_disk_t disk;
static int scan_depth = 0;
@@ -196,12 +199,12 @@ scan_disk (const char *name, int accept_diskfilter)
scan_depth--;
return 0;
}
- if (hook (disk, 0))
+ if (scan_disk_partition_iter (disk, 0, (void *) name))
{
scan_depth--;
return 1;
}
- if (grub_partition_iterate (disk, hook))
+ if (grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name))
{
scan_depth--;
return 1;
@@ -212,7 +215,7 @@ scan_disk (const char *name, int accept_diskfilter)
}
static int
-scan_disk_hook (const char *name)
+scan_disk_hook (const char *name, void *data __attribute__ ((unused)))
{
return scan_disk (name, 0);
}
@@ -230,7 +233,7 @@ scan_devices (const char *arname)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate)
{
- if ((p->iterate) (scan_disk_hook, pull))
+ if ((p->iterate) (scan_disk_hook, NULL, pull))
return;
if (arname && is_lv_readable (find_lv (arname), 1))
return;
@@ -249,8 +252,8 @@ scan_devices (const char *arname)
}
static int
-grub_diskfilter_iterate (int (*hook) (const char *name),
- grub_disk_pull_t pull)
+grub_diskfilter_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
struct grub_diskfilter_vg *array;
int islcnt = 0;
@@ -271,7 +274,7 @@ grub_diskfilter_iterate (int (*hook) (const char *name),
for (lv = array->lvs; lv; lv = lv->next)
if (lv->visible && lv->fullname && lv->became_readable_at >= islcnt)
{
- if (hook (lv->fullname))
+ if (hook (lv->fullname, hook_data))
return 1;
}
}
@@ -303,7 +306,7 @@ grub_diskfilter_memberlist (grub_disk_t disk)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate)
{
- (p->iterate) (scan_disk_hook, pull);
+ (p->iterate) (scan_disk_hook, NULL, pull);
while (pv && pv->disk)
pv = pv->next;
}
@@ -831,7 +834,8 @@ grub_diskfilter_write (grub_disk_t disk __attribute ((unused)),
grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
- return GRUB_ERR_NOT_IMPLEMENTED_YET;
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ "diskfilter writes are not supported");
}
struct grub_diskfilter_vg *
diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
index d9d788c..98cd226 100644
--- a/grub-core/disk/efi/efidisk.c
+++ b/grub-core/disk/efi/efidisk.c
@@ -404,7 +404,7 @@ enumerate_disks (void)
}
static int
-grub_efidisk_iterate (int (*hook) (const char *name),
+grub_efidisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
struct grub_efidisk_data *d;
@@ -418,7 +418,7 @@ grub_efidisk_iterate (int (*hook) (const char *name),
{
grub_snprintf (buf, sizeof (buf), "hd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
break;
@@ -427,7 +427,7 @@ grub_efidisk_iterate (int (*hook) (const char *name),
{
grub_snprintf (buf, sizeof (buf), "fd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
@@ -435,7 +435,7 @@ grub_efidisk_iterate (int (*hook) (const char *name),
{
grub_snprintf (buf, sizeof (buf), "cd%d", count);
grub_dprintf ("efidisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
break;
@@ -736,6 +736,31 @@ get_diskname_from_path (const grub_efi_device_path_t *path,
return 0;
}
+/* Context for grub_efidisk_get_device_name. */
+struct grub_efidisk_get_device_name_ctx
+{
+ char *partition_name;
+ grub_efi_hard_drive_device_path_t hd;
+};
+
+/* Helper for grub_efidisk_get_device_name.
+ Find the identical partition. */
+static int
+grub_efidisk_get_device_name_iter (grub_disk_t disk __attribute__ ((unused)),
+ const grub_partition_t part, void *data)
+{
+ struct grub_efidisk_get_device_name_ctx *ctx = data;
+
+ if (grub_partition_get_start (part) == ctx->hd.partition_start
+ && grub_partition_get_len (part) == ctx->hd.partition_size)
+ {
+ ctx->partition_name = grub_partition_get_name (part);
+ return 1;
+ }
+
+ return 0;
+}
+
char *
grub_efidisk_get_device_name (grub_efi_handle_t *handle)
{
@@ -754,28 +779,11 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
== GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
{
- char *partition_name = NULL;
+ struct grub_efidisk_get_device_name_ctx ctx;
char *dev_name;
grub_efi_device_path_t *dup_dp, *dup_ldp;
- grub_efi_hard_drive_device_path_t hd;
grub_disk_t parent = 0;
- auto int find_partition (grub_disk_t disk, const grub_partition_t part);
-
- /* Find the identical partition. */
- int find_partition (grub_disk_t disk __attribute__ ((unused)),
- const grub_partition_t part)
- {
- if (grub_partition_get_start (part) == hd.partition_start
- && grub_partition_get_len (part) == hd.partition_size)
- {
- partition_name = grub_partition_get_name (part);
- return 1;
- }
-
- return 0;
- }
-
/* It is necessary to duplicate the device path so that GRUB
can overwrite it. */
dup_dp = duplicate_device_path (dp);
@@ -797,24 +805,27 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
return 0;
/* Find a partition which matches the hard drive device path. */
- grub_memcpy (&hd, ldp, sizeof (hd));
- if (hd.partition_start == 0
- && hd.partition_size == grub_disk_get_size (parent))
+ ctx.partition_name = NULL;
+ grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd));
+ if (ctx.hd.partition_start == 0
+ && ctx.hd.partition_size == grub_disk_get_size (parent))
{
dev_name = grub_strdup (parent->name);
}
else
{
- grub_partition_iterate (parent, find_partition);
+ grub_partition_iterate (parent, grub_efidisk_get_device_name_iter,
+ &ctx);
- if (! partition_name)
+ if (! ctx.partition_name)
{
grub_disk_close (parent);
return 0;
}
- dev_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
- grub_free (partition_name);
+ dev_name = grub_xasprintf ("%s,%s", parent->name,
+ ctx.partition_name);
+ grub_free (ctx.partition_name);
}
grub_disk_close (parent);
diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c
index 5ee0d2e..959211b 100644
--- a/grub-core/disk/host.c
+++ b/grub-core/disk/host.c
@@ -27,13 +27,13 @@
int grub_disk_host_i_want_a_reference;
static int
-grub_host_iterate (int (*hook) (const char *name),
+grub_host_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
if (pull != GRUB_DISK_PULL_NONE)
return 0;
- if (hook ("host"))
+ if (hook ("host", hook_data))
return 1;
return 0;
}
diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c
index 7ca89e3..7c8dca3 100644
--- a/grub-core/disk/i386/pc/biosdisk.c
+++ b/grub-core/disk/i386/pc/biosdisk.c
@@ -272,20 +272,21 @@ grub_biosdisk_get_drive (const char *name)
}
static int
-grub_biosdisk_call_hook (int (*hook) (const char *name), int drive)
+grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ int drive)
{
char name[10];
if (cd_drive && drive == cd_drive)
- return hook ("cd");
+ return hook ("cd", hook_data);
grub_snprintf (name, sizeof (name),
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
- return hook (name);
+ return hook (name, hook_data);
}
static int
-grub_biosdisk_iterate (int (*hook) (const char *name),
+grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull __attribute__ ((unused)))
{
int num_floppies;
@@ -304,7 +305,7 @@ grub_biosdisk_iterate (int (*hook) (const char *name),
break;
}
- if (grub_biosdisk_call_hook (hook, drive))
+ if (grub_biosdisk_call_hook (hook, hook_data, drive))
return 1;
}
return 0;
@@ -312,14 +313,14 @@ grub_biosdisk_iterate (int (*hook) (const char *name),
case GRUB_DISK_PULL_REMOVABLE:
if (cd_drive)
{
- if (grub_biosdisk_call_hook (hook, cd_drive))
+ if (grub_biosdisk_call_hook (hook, hook_data, cd_drive))
return 1;
}
/* For floppy disks, we can get the number safely. */
num_floppies = grub_biosdisk_get_num_floppies ();
for (drive = 0; drive < num_floppies; drive++)
- if (grub_biosdisk_call_hook (hook, drive))
+ if (grub_biosdisk_call_hook (hook, hook_data, drive))
return 1;
return 0;
default:
diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c
index ad30852..b2844b1 100644
--- a/grub-core/disk/ieee1275/nand.c
+++ b/grub-core/disk/ieee1275/nand.c
@@ -33,7 +33,7 @@ struct grub_nand_data
};
static int
-grub_nand_iterate (int (*hook) (const char *name),
+grub_nand_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
auto int dev_iterate (struct grub_ieee1275_devalias *alias);
@@ -41,7 +41,7 @@ grub_nand_iterate (int (*hook) (const char *name),
{
if (grub_strcmp (alias->name, "nand") == 0)
{
- hook (alias->name);
+ hook (alias->name, hook_data);
return 1;
}
@@ -203,7 +203,8 @@ grub_nand_write (grub_disk_t disk __attribute ((unused)),
grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
- return GRUB_ERR_NOT_IMPLEMENTED_YET;
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ "nand write is not supported");
}
static struct grub_disk_dev grub_nand_dev =
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
index c9535a0..644bbd2 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -218,7 +218,7 @@ scan (void)
}
static int
-grub_ofdisk_iterate (int (*hook) (const char *name),
+grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
unsigned i;
@@ -276,7 +276,7 @@ grub_ofdisk_iterate (int (*hook) (const char *name),
*optr++ = *iptr++;
}
*optr = 0;
- if (hook (buffer))
+ if (hook (buffer, hook_data))
return 1;
}
}
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
index 0e4761b..b92433d 100644
--- a/grub-core/disk/ldm.c
+++ b/grub-core/disk/ldm.c
@@ -105,35 +105,39 @@ read_int (grub_uint8_t *in, grub_size_t s)
static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM;
+/* Helper for gpt_ldm_sector. */
+static int
+gpt_ldm_sector_iter (grub_disk_t disk, const grub_partition_t p, void *data)
+{
+ grub_disk_addr_t *sector = data;
+ struct grub_gpt_partentry gptdata;
+ grub_partition_t p2;
+
+ p2 = disk->partition;
+ disk->partition = p->parent;
+ if (grub_disk_read (disk, p->offset, p->index,
+ sizeof (gptdata), &gptdata))
+ {
+ disk->partition = p2;
+ return 0;
+ }
+ disk->partition = p2;
+
+ if (! grub_memcmp (&gptdata.type, &ldm_type, 16))
+ {
+ *sector = p->start + p->len - 1;
+ return 1;
+ }
+ return 0;
+}
+
static grub_disk_addr_t
gpt_ldm_sector (grub_disk_t dsk)
{
grub_disk_addr_t sector = 0;
grub_err_t err;
- auto int hook (grub_disk_t disk, const grub_partition_t p);
- int hook (grub_disk_t disk, const grub_partition_t p)
- {
- struct grub_gpt_partentry gptdata;
- grub_partition_t p2;
-
- p2 = disk->partition;
- disk->partition = p->parent;
- if (grub_disk_read (disk, p->offset, p->index,
- sizeof (gptdata), &gptdata))
- {
- disk->partition = p2;
- return 0;
- }
- disk->partition = p2;
- if (! grub_memcmp (&gptdata.type, &ldm_type, 16))
- {
- sector = p->start + p->len - 1;
- return 1;
- }
- return 0;
- }
- err = grub_gpt_partition_map_iterate (dsk, hook);
+ err = grub_gpt_partition_map_iterate (dsk, gpt_ldm_sector_iter, &sector);
if (err)
{
grub_errno = GRUB_ERR_NONE;
diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c
index f3b19ef..fed88de 100644
--- a/grub-core/disk/loopback.c
+++ b/grub-core/disk/loopback.c
@@ -135,15 +135,15 @@ fail:
static int
-grub_loopback_iterate (int (*hook) (const char *name),
- grub_disk_pull_t pull)
+grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
struct grub_loopback *d;
if (pull != GRUB_DISK_PULL_NONE)
return 0;
for (d = loopback_list; d; d = d->next)
{
- if (hook (d->devname))
+ if (hook (d->devname, hook_data))
return 1;
}
return 0;
@@ -206,7 +206,8 @@ grub_loopback_write (grub_disk_t disk __attribute ((unused)),
grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
- return GRUB_ERR_NOT_IMPLEMENTED_YET;
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ "loopback write is not supported");
}
static struct grub_disk_dev grub_loopback_dev =
diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c
index 4de0971..4ad1cb1 100644
--- a/grub-core/disk/memdisk.c
+++ b/grub-core/disk/memdisk.c
@@ -30,13 +30,13 @@ static char *memdisk_addr;
static grub_off_t memdisk_size = 0;
static int
-grub_memdisk_iterate (int (*hook) (const char *name),
+grub_memdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
if (pull != GRUB_DISK_PULL_NONE)
return 0;
- return hook ("memdisk");
+ return hook ("memdisk", hook_data);
}
static grub_err_t
diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c
index 00b04e2..75e5deb 100644
--- a/grub-core/disk/pata.c
+++ b/grub-core/disk/pata.c
@@ -338,9 +338,10 @@ grub_pata_device_initialize (int port, int device, int addr)
}
#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
-static int NESTED_FUNC_ATTR
+static int
grub_pata_pciinit (grub_pci_device_t dev,
- grub_pci_id_t pciid)
+ grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
{
static int compat_use[2] = { 0 };
grub_pci_address_t addr;
@@ -446,7 +447,7 @@ grub_pata_pciinit (grub_pci_device_t dev,
static grub_err_t
grub_pata_initialize (void)
{
- grub_pci_iterate (grub_pata_pciinit);
+ grub_pci_iterate (grub_pata_pciinit, NULL);
return 0;
}
#else
@@ -500,7 +501,7 @@ grub_pata_open (int id, int devnum, struct grub_ata *ata)
}
static int
-grub_pata_iterate (int (*hook) (int id, int bus),
+grub_pata_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
struct grub_pata_device *dev;
@@ -509,7 +510,8 @@ grub_pata_iterate (int (*hook) (int id, int bus),
return 0;
for (dev = grub_pata_devices; dev; dev = dev->next)
- if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device))
+ if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device,
+ hook_data))
return 1;
return 0;
diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c
index 29dd0d3..90ac379 100644
--- a/grub-core/disk/scsi.c
+++ b/grub-core/disk/scsi.c
@@ -423,50 +423,59 @@ grub_scsi_write16 (grub_disk_t disk, grub_disk_addr_t sector,
-static int
-grub_scsi_iterate (int (*hook) (const char *name),
- grub_disk_pull_t pull)
+/* Context for grub_scsi_iterate. */
+struct grub_scsi_iterate_ctx
{
- grub_scsi_dev_t p;
+ grub_disk_dev_iterate_hook_t hook;
+ void *hook_data;
+};
- auto int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns);
+/* Helper for grub_scsi_iterate. */
+static int
+scsi_iterate (int id, int bus, int luns, void *data)
+{
+ struct grub_scsi_iterate_ctx *ctx = data;
+ int i;
- int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns)
+ /* In case of a single LUN, just return `usbX'. */
+ if (luns == 1)
{
- int i;
-
- /* In case of a single LUN, just return `usbX'. */
- if (luns == 1)
- {
- char *sname;
- int ret;
- sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus);
- if (!sname)
- return 1;
- ret = hook (sname);
- grub_free (sname);
- return ret;
- }
+ char *sname;
+ int ret;
+ sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus);
+ if (!sname)
+ return 1;
+ ret = ctx->hook (sname, ctx->hook_data);
+ grub_free (sname);
+ return ret;
+ }
- /* In case of multiple LUNs, every LUN will get a prefix to
- distinguish it. */
- for (i = 0; i < luns; i++)
- {
- char *sname;
- int ret;
- sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i);
- if (!sname)
- return 1;
- ret = hook (sname);
- grub_free (sname);
- if (ret)
- return 1;
- }
- return 0;
+ /* In case of multiple LUNs, every LUN will get a prefix to
+ distinguish it. */
+ for (i = 0; i < luns; i++)
+ {
+ char *sname;
+ int ret;
+ sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i);
+ if (!sname)
+ return 1;
+ ret = ctx->hook (sname, ctx->hook_data);
+ grub_free (sname);
+ if (ret)
+ return 1;
}
+ return 0;
+}
+
+static int
+grub_scsi_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
+{
+ struct grub_scsi_iterate_ctx ctx = { hook, hook_data };
+ grub_scsi_dev_t p;
for (p = grub_scsi_dev_list; p; p = p->next)
- if (p->iterate && (p->iterate) (scsi_iterate, pull))
+ if (p->iterate && (p->iterate) (scsi_iterate, &ctx, pull))
return 1;
return 0;
diff --git a/grub-core/disk/uboot/ubootdisk.c b/grub-core/disk/uboot/ubootdisk.c
index 2ef4359..54659b5 100644
--- a/grub-core/disk/uboot/ubootdisk.c
+++ b/grub-core/disk/uboot/ubootdisk.c
@@ -100,7 +100,8 @@ grub_ubootdisk_register (struct device_info *newdev, int handle)
* Itarator over enumerated disk devices.
*/
static int
-uboot_disk_iterate (int (*hook) (const char *name), grub_disk_pull_t pull)
+uboot_disk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+ grub_disk_pull_t pull)
{
struct ubootdisk_data *d;
char buf[16];
@@ -114,7 +115,7 @@ uboot_disk_iterate (int (*hook) (const char *name), grub_disk_pull_t pull)
{
grub_snprintf (buf, sizeof (buf) - 1, "hd%d", count);
grub_dprintf ("ubootdisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
break;
@@ -124,7 +125,7 @@ uboot_disk_iterate (int (*hook) (const char *name), grub_disk_pull_t pull)
{
grub_snprintf (buf, sizeof (buf) - 1, "fd%d", count);
grub_dprintf ("ubootdisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
@@ -133,7 +134,7 @@ uboot_disk_iterate (int (*hook) (const char *name), grub_disk_pull_t pull)
{
grub_snprintf (buf, sizeof (buf) - 1, "cd%d", count);
grub_dprintf ("ubootdisk", "iterating %s\n", buf);
- if (hook (buf))
+ if (hook (buf, hook_data))
return 1;
}
break;
diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c
index 52cc33e..50f0caf 100644
--- a/grub-core/disk/usbms.c
+++ b/grub-core/disk/usbms.c
@@ -265,7 +265,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno)
static int
-grub_usbms_iterate (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns),
+grub_usbms_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
unsigned i;
@@ -278,7 +278,8 @@ grub_usbms_iterate (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns),
for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
if (grub_usbms_devices[i])
{
- if (hook (GRUB_SCSI_SUBSYSTEM_USBMS, i, grub_usbms_devices[i]->luns))
+ if (hook (GRUB_SCSI_SUBSYSTEM_USBMS, i, grub_usbms_devices[i]->luns,
+ hook_data))
return 1;
}
diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c
index 10cbc68..d4a4f3a 100644
--- a/grub-core/efiemu/mm.c
+++ b/grub-core/efiemu/mm.c
@@ -268,26 +268,26 @@ grub_efiemu_mm_return_request (int handle)
}
}
+/* Helper for grub_efiemu_mmap_init. */
+static int
+bounds_hook (grub_uint64_t addr __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
+ grub_memory_type_t type __attribute__ ((unused)),
+ void *data __attribute__ ((unused)))
+{
+ mmap_reserved_size++;
+ return 0;
+}
+
/* Reserve space for memory map */
static grub_err_t
grub_efiemu_mmap_init (void)
{
- auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)),
- grub_uint64_t size __attribute__ ((unused)),
- grub_memory_type_t type
- __attribute__ ((unused)))
- {
- mmap_reserved_size++;
- return 0;
- }
-
// the place for memory used by efiemu itself
mmap_reserved_size = GRUB_EFI_MAX_MEMORY_TYPE + 1;
#ifndef GRUB_MACHINE_EMU
- grub_machine_mmap_iterate (bounds_hook);
+ grub_machine_mmap_iterate (bounds_hook, NULL);
#endif
return GRUB_ERR_NONE;
@@ -383,48 +383,47 @@ grub_efiemu_mm_init (void)
return GRUB_ERR_NONE;
}
+/* Helper for grub_efiemu_mmap_fill. */
+static int
+fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data __attribute__ ((unused)))
+ {
+ switch (type)
+ {
+ case GRUB_MEMORY_AVAILABLE:
+ return grub_efiemu_add_to_mmap (addr, size,
+ GRUB_EFI_CONVENTIONAL_MEMORY);
+
+ case GRUB_MEMORY_ACPI:
+ return grub_efiemu_add_to_mmap (addr, size,
+ GRUB_EFI_ACPI_RECLAIM_MEMORY);
+
+ case GRUB_MEMORY_NVS:
+ return grub_efiemu_add_to_mmap (addr, size,
+ GRUB_EFI_ACPI_MEMORY_NVS);
+
+ default:
+ grub_dprintf ("efiemu",
+ "Unknown memory type %d. Assuming unusable\n", type);
+ case GRUB_MEMORY_RESERVED:
+ return grub_efiemu_add_to_mmap (addr, size,
+ GRUB_EFI_UNUSABLE_MEMORY);
+ }
+ }
+
/* Copy host memory map */
static grub_err_t
grub_efiemu_mmap_fill (void)
{
- auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
- grub_uint64_t size,
- grub_memory_type_t type)
- {
- switch (type)
- {
- case GRUB_MEMORY_AVAILABLE:
- return grub_efiemu_add_to_mmap (addr, size,
- GRUB_EFI_CONVENTIONAL_MEMORY);
-
- case GRUB_MEMORY_ACPI:
- return grub_efiemu_add_to_mmap (addr, size,
- GRUB_EFI_ACPI_RECLAIM_MEMORY);
-
- case GRUB_MEMORY_NVS:
- return grub_efiemu_add_to_mmap (addr, size,
- GRUB_EFI_ACPI_MEMORY_NVS);
-
- default:
- grub_dprintf ("efiemu",
- "Unknown memory type %d. Assuming unusable\n", type);
- case GRUB_MEMORY_RESERVED:
- return grub_efiemu_add_to_mmap (addr, size,
- GRUB_EFI_UNUSABLE_MEMORY);
- }
- }
-
#ifndef GRUB_MACHINE_EMU
- grub_machine_mmap_iterate (fill_hook);
+ grub_machine_mmap_iterate (fill_hook, NULL);
#endif
return GRUB_ERR_NONE;
}
grub_err_t
-grub_efiemu_mmap_iterate (grub_memory_hook_t hook)
+grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
unsigned i;
@@ -433,12 +432,12 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook)
{
case GRUB_EFI_RUNTIME_SERVICES_CODE:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
- GRUB_MEMORY_CODE);
+ GRUB_MEMORY_CODE, hook_data);
break;
case GRUB_EFI_UNUSABLE_MEMORY:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
- GRUB_MEMORY_BADRAM);
+ GRUB_MEMORY_BADRAM, hook_data);
break;
case GRUB_EFI_RESERVED_MEMORY_TYPE:
@@ -448,7 +447,7 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook)
case GRUB_EFI_PAL_CODE:
case GRUB_EFI_MAX_MEMORY_TYPE:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
- GRUB_MEMORY_RESERVED);
+ GRUB_MEMORY_RESERVED, hook_data);
break;
case GRUB_EFI_LOADER_CODE:
@@ -457,17 +456,17 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook)
case GRUB_EFI_BOOT_SERVICES_DATA:
case GRUB_EFI_CONVENTIONAL_MEMORY:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
- GRUB_MEMORY_AVAILABLE);
+ GRUB_MEMORY_AVAILABLE, hook_data);
break;
case GRUB_EFI_ACPI_RECLAIM_MEMORY:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
- GRUB_MEMORY_ACPI);
+ GRUB_MEMORY_ACPI, hook_data);
break;
case GRUB_EFI_ACPI_MEMORY_NVS:
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
- GRUB_MEMORY_NVS);
+ GRUB_MEMORY_NVS, hook_data);
break;
}
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index fca8c8d..6b54a84 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1143,6 +1143,49 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
}
}
+/* Context for blit_comb. */
+struct blit_comb_ctx
+{
+ struct grub_font_glyph *glyph;
+ int *device_width;
+ struct grub_video_signed_rect bounds;
+};
+
+/* Helper for blit_comb. */
+static void
+do_blit (struct grub_font_glyph *src, signed dx, signed dy,
+ struct blit_comb_ctx *ctx)
+{
+ if (ctx->glyph)
+ grub_font_blit_glyph (ctx->glyph, src, dx - ctx->glyph->offset_x,
+ (ctx->glyph->height + ctx->glyph->offset_y) + dy);
+ if (dx < ctx->bounds.x)
+ {
+ ctx->bounds.width += ctx->bounds.x - dx;
+ ctx->bounds.x = dx;
+ }
+ if (ctx->bounds.y > -src->height - dy)
+ {
+ ctx->bounds.height += ctx->bounds.y - (-src->height - dy);
+ ctx->bounds.y = (-src->height - dy);
+ }
+ if (dx + src->width - ctx->bounds.x >= (signed) ctx->bounds.width)
+ ctx->bounds.width = dx + src->width - ctx->bounds.x + 1;
+ if ((signed) ctx->bounds.height < src->height + (-src->height - dy)
+ - ctx->bounds.y)
+ ctx->bounds.height = src->height + (-src->height - dy) - ctx->bounds.y;
+}
+
+/* Helper for blit_comb. */
+static inline void
+add_device_width (int val, struct blit_comb_ctx *ctx)
+{
+ if (ctx->glyph)
+ ctx->glyph->device_width += val;
+ if (ctx->device_width)
+ *ctx->device_width += val;
+}
+
static void
blit_comb (const struct grub_unicode_glyph *glyph_id,
struct grub_font_glyph *glyph,
@@ -1150,63 +1193,34 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
struct grub_font_glyph *main_glyph,
struct grub_font_glyph **combining_glyphs, int *device_width)
{
- struct grub_video_signed_rect bounds;
+ struct blit_comb_ctx ctx = {
+ .glyph = glyph,
+ .device_width = device_width
+ };
unsigned i;
signed above_rightx, above_righty;
signed above_leftx, above_lefty;
signed below_rightx, below_righty;
signed min_devwidth = 0;
- auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
- signed dx, signed dy);
- void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
- signed dx, signed dy)
- {
- if (glyph)
- grub_font_blit_glyph (glyph, src, dx - glyph->offset_x,
- (glyph->height + glyph->offset_y) + dy);
- if (dx < bounds.x)
- {
- bounds.width += bounds.x - dx;
- bounds.x = dx;
- }
- if (bounds.y > -src->height - dy)
- {
- bounds.height += bounds.y - (-src->height - dy);
- bounds.y = (-src->height - dy);
- }
- if (dx + src->width - bounds.x >= (signed) bounds.width)
- bounds.width = dx + src->width - bounds.x + 1;
- if ((signed) bounds.height < src->height + (-src->height - dy) - bounds.y)
- bounds.height = src->height + (-src->height - dy) - bounds.y;
- }
-
- auto void add_device_width (int val);
- void add_device_width (int val)
- {
- if (glyph)
- glyph->device_width += val;
- if (device_width)
- *device_width += val;
- }
if (glyph)
glyph->device_width = main_glyph->device_width;
if (device_width)
*device_width = main_glyph->device_width;
- bounds.x = main_glyph->offset_x;
- bounds.y = main_glyph->offset_y;
- bounds.width = main_glyph->width;
- bounds.height = main_glyph->height;
+ ctx.bounds.x = main_glyph->offset_x;
+ ctx.bounds.y = main_glyph->offset_y;
+ ctx.bounds.width = main_glyph->width;
+ ctx.bounds.height = main_glyph->height;
above_rightx = main_glyph->offset_x + main_glyph->width;
- above_righty = bounds.y + bounds.height;
+ above_righty = ctx.bounds.y + ctx.bounds.height;
above_leftx = main_glyph->offset_x;
- above_lefty = bounds.y + bounds.height;
+ above_lefty = ctx.bounds.y + ctx.bounds.height;
- below_rightx = bounds.x + bounds.width;
- below_righty = bounds.y;
+ below_rightx = ctx.bounds.x + ctx.bounds.width;
+ below_righty = ctx.bounds.y;
for (i = 0; i < glyph_id->ncomb; i++)
{
@@ -1216,7 +1230,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
if (!combining_glyphs[i])
continue;
- targetx = (bounds.width - combining_glyphs[i]->width) / 2 + bounds.x;
+ targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
/* CGJ is to avoid diacritics reordering. */
if (glyph_id->combining[i].code
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
@@ -1226,31 +1240,31 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
case GRUB_UNICODE_COMB_OVERLAY:
do_blit (combining_glyphs[i],
targetx,
- (bounds.height - combining_glyphs[i]->height) / 2
- - (bounds.height + bounds.y));
+ (ctx.bounds.height - combining_glyphs[i]->height) / 2
+ - (ctx.bounds.height + ctx.bounds.y), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT:
- do_blit (combining_glyphs[i], above_rightx, -above_righty);
+ do_blit (combining_glyphs[i], above_rightx, -above_righty, &ctx);
above_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ABOVE_RIGHT:
do_blit (combining_glyphs[i], above_rightx,
- -(above_righty + combining_glyphs[i]->height));
+ -(above_righty + combining_glyphs[i]->height), &ctx);
above_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ABOVE_LEFT:
above_leftx -= combining_glyphs[i]->width;
do_blit (combining_glyphs[i], above_leftx,
- -(above_lefty + combining_glyphs[i]->height));
+ -(above_lefty + combining_glyphs[i]->height), &ctx);
break;
case GRUB_UNICODE_COMB_BELOW_RIGHT:
- do_blit (combining_glyphs[i], below_rightx, below_righty);
+ do_blit (combining_glyphs[i], below_rightx, below_righty, &ctx);
below_rightx += combining_glyphs[i]->width;
break;
@@ -1276,7 +1290,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
do_blit (combining_glyphs[i], targetx,
-(main_glyph->height + main_glyph->offset_y + space
- + combining_glyphs[i]->height));
+ + combining_glyphs[i]->height), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
@@ -1300,16 +1314,16 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
do_blit (combining_glyphs[i], targetx,
- -(bounds.height + bounds.y + space
- + combining_glyphs[i]->height));
+ -(ctx.bounds.height + ctx.bounds.y + space
+ + combining_glyphs[i]->height), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_HEBREW_DAGESH:
do_blit (combining_glyphs[i], targetx,
- -(bounds.height / 2 + bounds.y
- + combining_glyphs[i]->height / 2));
+ -(ctx.bounds.height / 2 + ctx.bounds.y
+ + combining_glyphs[i]->height / 2), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
@@ -1340,7 +1354,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
case GRUB_UNICODE_STACK_ATTACHED_BELOW:
- do_blit (combining_glyphs[i], targetx, -(bounds.y - space));
+ do_blit (combining_glyphs[i], targetx, -(ctx.bounds.y - space),
+ &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
@@ -1373,22 +1388,22 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
main_glyph->device_width
+ combining_glyphs[i]->offset_x,
-(combining_glyphs[i]->height
- + combining_glyphs[i]->offset_y));
- add_device_width (combining_glyphs[i]->device_width);
+ + combining_glyphs[i]->offset_y), &ctx);
+ add_device_width (combining_glyphs[i]->device_width, &ctx);
}
}
}
add_device_width ((above_rightx >
below_rightx ? above_rightx : below_rightx) -
- (main_glyph->offset_x + main_glyph->width));
- add_device_width (above_leftx - main_glyph->offset_x);
+ (main_glyph->offset_x + main_glyph->width), &ctx);
+ add_device_width (above_leftx - main_glyph->offset_x, &ctx);
if (glyph && glyph->device_width < min_devwidth)
glyph->device_width = min_devwidth;
if (device_width && *device_width < min_devwidth)
*device_width = min_devwidth;
if (bounds_out)
- *bounds_out = bounds;
+ *bounds_out = ctx.bounds;
}
static struct grub_font_glyph *
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
index 848a455..6c49e5d 100644
--- a/grub-core/fs/affs.c
+++ b/grub-core/fs/affs.c
@@ -316,93 +316,93 @@ grub_affs_read_symlink (grub_fshelp_node_t node)
}
+/* Helper for grub_affs_iterate_dir. */
static int
-grub_affs_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+grub_affs_create_node (grub_fshelp_node_t dir,
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data,
+ struct grub_fshelp_node **node,
+ grub_uint32_t **hashtable,
+ grub_uint32_t block, const struct grub_affs_file *fil)
{
- unsigned int i;
- struct grub_affs_file file;
- struct grub_fshelp_node *node = 0;
struct grub_affs_data *data = dir->data;
- grub_uint32_t *hashtable;
-
- auto int NESTED_FUNC_ATTR grub_affs_create_node (grub_uint32_t block,
- const struct grub_affs_file *fil);
+ int type;
+ grub_uint8_t name_u8[sizeof (fil->name) * GRUB_MAX_UTF8_PER_LATIN1 + 1];
+ grub_size_t len;
+ unsigned int nest;
- int NESTED_FUNC_ATTR grub_affs_create_node (grub_uint32_t block,
- const struct grub_affs_file *fil)
+ *node = grub_zalloc (sizeof (**node));
+ if (!*node)
{
- int type;
- grub_uint8_t name_u8[sizeof (fil->name) * GRUB_MAX_UTF8_PER_LATIN1 + 1];
- grub_size_t len;
- unsigned int nest;
-
- node = grub_zalloc (sizeof (*node));
- if (!node)
- {
- grub_free (hashtable);
- return 1;
- }
+ grub_free (*hashtable);
+ return 1;
+ }
- node->data = data;
- node->block = block;
- node->parent = dir;
-
- len = fil->namelen;
- if (len > sizeof (fil->name))
- len = sizeof (fil->name);
- *grub_latin1_to_utf8 (name_u8, fil->name, len) = '\0';
-
- node->di = *fil;
- for (nest = 0; nest < 8; nest++)
+ (*node)->data = data;
+ (*node)->block = block;
+ (*node)->parent = dir;
+
+ len = fil->namelen;
+ if (len > sizeof (fil->name))
+ len = sizeof (fil->name);
+ *grub_latin1_to_utf8 (name_u8, fil->name, len) = '\0';
+
+ (*node)->di = *fil;
+ for (nest = 0; nest < 8; nest++)
+ {
+ switch ((*node)->di.type)
{
- switch (node->di.type)
- {
- case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_REG):
- type = GRUB_FSHELP_REG;
- break;
- case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_DIR):
- type = GRUB_FSHELP_DIR;
- break;
- case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_SYMLINK):
- type = GRUB_FSHELP_SYMLINK;
- break;
- case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_HARDLINK):
- {
- grub_err_t err;
- node->block = grub_be_to_cpu32 (node->di.hardlink);
- err = grub_disk_read (data->disk,
- (((grub_uint64_t) node->block + 1) << data->log_blocksize)
- - 1,
- GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION,
- sizeof (node->di), (char *) &node->di);
- if (err)
- return 1;
- continue;
- }
- default:
- return 0;
- }
+ case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_REG):
+ type = GRUB_FSHELP_REG;
+ break;
+ case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_DIR):
+ type = GRUB_FSHELP_DIR;
+ break;
+ case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_SYMLINK):
+ type = GRUB_FSHELP_SYMLINK;
break;
+ case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_HARDLINK):
+ {
+ grub_err_t err;
+ (*node)->block = grub_be_to_cpu32 ((*node)->di.hardlink);
+ err = grub_disk_read (data->disk,
+ (((grub_uint64_t) (*node)->block + 1) << data->log_blocksize)
+ - 1,
+ GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION,
+ sizeof ((*node)->di), (char *) &(*node)->di);
+ if (err)
+ return 1;
+ continue;
+ }
+ default:
+ return 0;
}
+ break;
+ }
- if (nest == 8)
- return 0;
+ if (nest == 8)
+ return 0;
- type |= GRUB_FSHELP_CASE_INSENSITIVE;
+ type |= GRUB_FSHELP_CASE_INSENSITIVE;
- if (hook ((char *) name_u8, type, node))
- {
- grub_free (hashtable);
- node = 0;
- return 1;
- }
- node = 0;
- return 0;
+ if (hook ((char *) name_u8, type, *node, hook_data))
+ {
+ grub_free (*hashtable);
+ *node = 0;
+ return 1;
}
+ *node = 0;
+ return 0;
+}
+
+static int
+grub_affs_iterate_dir (grub_fshelp_node_t dir,
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
+{
+ unsigned int i;
+ struct grub_affs_file file;
+ struct grub_fshelp_node *node = 0;
+ struct grub_affs_data *data = dir->data;
+ grub_uint32_t *hashtable;
/* Create the directory entries for `.' and `..'. */
node = grub_zalloc (sizeof (*node));
@@ -410,7 +410,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
return 1;
*node = *dir;
- if (hook (".", GRUB_FSHELP_DIR, node))
+ if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
return 1;
if (dir->parent)
{
@@ -418,7 +418,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
if (!node)
return 1;
*node = *dir->parent;
- if (hook ("..", GRUB_FSHELP_DIR, node))
+ if (hook ("..", GRUB_FSHELP_DIR, node, hook_data))
return 1;
}
@@ -454,7 +454,8 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
if (grub_errno)
goto fail;
- if (grub_affs_create_node (next, &file))
+ if (grub_affs_create_node (dir, hook, hook_data, &node, &hashtable,
+ next, &file))
return 1;
next = grub_be_to_cpu32 (file.next);
@@ -545,31 +546,37 @@ aftime2ctime (const struct grub_affs_time *t)
+ 8 * 365 * 86400 + 86400 * 2;
}
+/* Context for grub_affs_dir. */
+struct grub_affs_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_affs_dir. */
+static int
+grub_affs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_affs_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ info.mtimeset = 1;
+ info.mtime = aftime2ctime (&node->di.mtime);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
static grub_err_t
grub_affs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
+ struct grub_affs_dir_ctx ctx = { hook, hook_data };
struct grub_affs_data *data = 0;
struct grub_fshelp_node *fdiro = 0;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- info.mtimeset = 1;
- info.mtime = aftime2ctime (&node->di.mtime);
- grub_free (node);
- return hook (filename, &info);
- }
-
grub_dl_ref (my_mod);
data = grub_affs_mount (device->disk);
@@ -581,7 +588,7 @@ grub_affs_dir (grub_device_t device, const char *path,
if (grub_errno)
goto fail;
- grub_affs_iterate_dir (fdiro, iterate);
+ grub_affs_iterate_dir (fdiro, grub_affs_dir_iter, &ctx);
fail:
if (data && fdiro != &data->diropen)
diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c
index 318dc3e..fa2fc3f 100644
--- a/grub-core/fs/bfs.c
+++ b/grub-core/fs/bfs.c
@@ -173,6 +173,15 @@ struct grub_bfs_data
struct grub_bfs_inode ino[0];
};
+/* Context for grub_bfs_dir. */
+struct grub_bfs_dir_ctx
+{
+ grub_device_t device;
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+ struct grub_bfs_superblock sb;
+};
+
static grub_err_t
read_extent (grub_disk_t disk,
const struct grub_bfs_superblock *sb,
@@ -413,7 +422,9 @@ static int
iterate_in_b_tree (grub_disk_t disk,
const struct grub_bfs_superblock *sb,
const struct grub_bfs_inode *ino,
- int NESTED_FUNC_ATTR (*hook) (const char *name, grub_uint64_t value))
+ int (*hook) (const char *name, grub_uint64_t value,
+ struct grub_bfs_dir_ctx *ctx),
+ struct grub_bfs_dir_ctx *ctx)
{
struct grub_bfs_btree_header head;
grub_err_t err;
@@ -496,7 +507,8 @@ iterate_in_b_tree (grub_disk_t disk,
end = grub_bfs_to_cpu_treehead (node.total_key_len);
c = key_data[end];
key_data[end] = 0;
- if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i])))
+ if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]),
+ ctx))
return 1;
key_data[end] = c;
}
@@ -844,46 +856,52 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb)
return GRUB_ERR_NONE;
}
-static grub_err_t
-grub_bfs_dir (grub_device_t device, const char *path,
- int (*hook_in) (const char *filename,
- const struct grub_dirhook_info * info))
+/* Helper for grub_bfs_dir. */
+static int
+grub_bfs_dir_iter (const char *name, grub_uint64_t value,
+ struct grub_bfs_dir_ctx *ctx)
{
- struct grub_bfs_superblock sb;
- grub_err_t err;
- auto int NESTED_FUNC_ATTR hook (const char *name, grub_uint64_t value);
-
- int NESTED_FUNC_ATTR hook (const char *name, grub_uint64_t value)
+ grub_err_t err2;
+ union
{
- grub_err_t err2;
- union
- {
- struct grub_bfs_inode ino;
- grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)];
- } ino;
- struct grub_dirhook_info info;
+ struct grub_bfs_inode ino;
+ grub_uint8_t raw[grub_bfs_to_cpu32 (ctx->sb.bsize)];
+ } ino;
+ struct grub_dirhook_info info;
- err2 = grub_disk_read (device->disk, value
- << (grub_bfs_to_cpu32 (sb.log2_bsize)
- - GRUB_DISK_SECTOR_BITS), 0,
- grub_bfs_to_cpu32 (sb.bsize), (char *) ino.raw);
- if (err2)
- {
- grub_print_error ();
- return 0;
- }
+ err2 = grub_disk_read (ctx->device->disk, value
+ << (grub_bfs_to_cpu32 (ctx->sb.log2_bsize)
+ - GRUB_DISK_SECTOR_BITS), 0,
+ grub_bfs_to_cpu32 (ctx->sb.bsize), (char *) ino.raw);
+ if (err2)
+ {
+ grub_print_error ();
+ return 0;
+ }
- info.mtimeset = 1;
+ info.mtimeset = 1;
#ifdef MODE_AFS
- info.mtime =
- grub_divmod64 (grub_bfs_to_cpu64 (ino.ino.mtime), 1000000, 0);
+ info.mtime =
+ grub_divmod64 (grub_bfs_to_cpu64 (ino.ino.mtime), 1000000, 0);
#else
- info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16;
+ info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16;
#endif
- info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR);
- return hook_in (name, &info);
- }
- err = mount (device->disk, &sb);
+ info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR);
+ return ctx->hook (name, &info, ctx->hook_data);
+}
+
+static grub_err_t
+grub_bfs_dir (grub_device_t device, const char *path,
+ grub_fs_dir_hook_t hook, void *hook_data)
+{
+ struct grub_bfs_dir_ctx ctx = {
+ .device = device,
+ .hook = hook,
+ .hook_data = hook_data
+ };
+ grub_err_t err;
+
+ err = mount (device->disk, &ctx.sb);
if (err)
return err;
@@ -891,14 +909,15 @@ grub_bfs_dir (grub_device_t device, const char *path,
union
{
struct grub_bfs_inode ino;
- grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)];
+ grub_uint8_t raw[grub_bfs_to_cpu32 (ctx.sb.bsize)];
} ino;
- err = find_file (path, device->disk, &sb, &ino.ino);
+ err = find_file (path, device->disk, &ctx.sb, &ino.ino);
if (err)
return err;
if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_DIR))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
- iterate_in_b_tree (device->disk, &sb, &ino.ino, hook);
+ iterate_in_b_tree (device->disk, &ctx.sb, &ino.ino, grub_bfs_dir_iter,
+ &ctx);
}
return grub_errno;
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
index a993f07..196f301 100644
--- a/grub-core/fs/btrfs.c
+++ b/grub-core/fs/btrfs.c
@@ -538,56 +538,71 @@ lower_bound (struct grub_btrfs_data *data,
}
}
-static grub_device_t
-find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
+/* Context for find_device. */
+struct find_device_ctx
{
- grub_device_t dev_found = NULL;
- auto int hook (const char *name);
- int hook (const char *name)
- {
- grub_device_t dev;
- grub_err_t err;
- struct grub_btrfs_superblock sb;
- dev = grub_device_open (name);
- if (!dev)
+ struct grub_btrfs_data *data;
+ grub_uint64_t id;
+ grub_device_t dev_found;
+};
+
+/* Helper for find_device. */
+static int
+find_device_iter (const char *name, void *data)
+{
+ struct find_device_ctx *ctx = data;
+ grub_device_t dev;
+ grub_err_t err;
+ struct grub_btrfs_superblock sb;
+
+ dev = grub_device_open (name);
+ if (!dev)
+ return 0;
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
return 0;
- if (!dev->disk)
- {
- grub_device_close (dev);
- return 0;
- }
- err = read_sblock (dev->disk, &sb);
- if (err == GRUB_ERR_BAD_FS)
- {
- grub_device_close (dev);
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- if (err)
- {
- grub_device_close (dev);
- grub_print_error ();
- return 0;
- }
- if (grub_memcmp (data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0
- || sb.this_device.device_id != id)
- {
- grub_device_close (dev);
- return 0;
- }
+ }
+ err = read_sblock (dev->disk, &sb);
+ if (err == GRUB_ERR_BAD_FS)
+ {
+ grub_device_close (dev);
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (err)
+ {
+ grub_device_close (dev);
+ grub_print_error ();
+ return 0;
+ }
+ if (grub_memcmp (ctx->data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0
+ || sb.this_device.device_id != ctx->id)
+ {
+ grub_device_close (dev);
+ return 0;
+ }
- dev_found = dev;
- return 1;
- }
+ ctx->dev_found = dev;
+ return 1;
+}
+static grub_device_t
+find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
+{
+ struct find_device_ctx ctx = {
+ .data = data,
+ .id = id,
+ .dev_found = NULL
+ };
unsigned i;
for (i = 0; i < data->n_devices_attached; i++)
if (id == data->devices_attached[i].id)
return data->devices_attached[i].dev;
if (do_rescan)
- grub_device_iterate (hook);
- if (!dev_found)
+ grub_device_iterate (find_device_iter, &ctx);
+ if (!ctx.dev_found)
{
grub_error (GRUB_ERR_BAD_FS,
N_("couldn't find a necessary member device "
@@ -605,14 +620,14 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
* sizeof (data->devices_attached[0]));
if (!data->devices_attached)
{
- grub_device_close (dev_found);
+ grub_device_close (ctx.dev_found);
data->devices_attached = tmp;
return NULL;
}
}
data->devices_attached[data->n_devices_attached - 1].id = id;
- data->devices_attached[data->n_devices_attached - 1].dev = dev_found;
- return dev_found;
+ data->devices_attached[data->n_devices_attached - 1].dev = ctx.dev_found;
+ return ctx.dev_found;
}
static grub_err_t
@@ -1476,8 +1491,7 @@ find_path (struct grub_btrfs_data *data,
static grub_err_t
grub_btrfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
struct grub_btrfs_data *data = grub_btrfs_mount (device);
struct grub_btrfs_key key_in, key_out;
@@ -1571,7 +1585,7 @@ grub_btrfs_dir (grub_device_t device, const char *path,
c = cdirel->name[grub_le_to_cpu16 (cdirel->n)];
cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0;
info.dir = (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY);
- if (hook (cdirel->name, &info))
+ if (hook (cdirel->name, &info, hook_data))
goto out;
cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c;
}
diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c
index e9236cd..71d7fa4 100644
--- a/grub-core/fs/cpio.c
+++ b/grub-core/fs/cpio.c
@@ -513,8 +513,7 @@ handle_symlink (struct grub_cpio_data *data,
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path_in,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
struct grub_cpio_data *data;
grub_disk_addr_t ofs;
@@ -575,7 +574,7 @@ grub_cpio_dir (grub_device_t device, const char *path_in,
info.mtime = mtime;
info.mtimeset = 1;
- if (hook (n, &info))
+ if (hook (n, &info, hook_data))
{
grub_free (name);
goto fail;
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
index bd1ab24..0ebde35 100644
--- a/grub-core/fs/ext2.c
+++ b/grub-core/fs/ext2.c
@@ -454,11 +454,12 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]);
}
/* Double indirect. */
- else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1))
+ else if (fileblock < INDIRECT_BLOCKS
+ + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1))
{
- unsigned int perblock = blksz / 4;
- unsigned int rblock = fileblock - (INDIRECT_BLOCKS
- + blksz / 4);
+ int log_perblock = log2_blksz + 9 - 2;
+ grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS
+ + blksz / 4);
grub_uint32_t indir[blksz / 4];
if (grub_disk_read (data->disk,
@@ -470,21 +471,22 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
if (grub_disk_read (data->disk,
((grub_disk_addr_t)
- grub_le_to_cpu32 (indir[rblock / perblock]))
+ grub_le_to_cpu32 (indir[rblock >> log_perblock]))
<< log2_blksz,
0, blksz, indir))
return grub_errno;
- blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
+ blknr = grub_le_to_cpu32 (indir[rblock & ((1 << log_perblock) - 1)]);
}
/* triple indirect. */
- else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1)
- + (blksz / 4) * (blksz / 4) * (blksz / 4 + 1))
+ else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1)
+ + ((grub_disk_addr_t) blksz / 4) * ((grub_disk_addr_t) blksz / 4)
+ * ((grub_disk_addr_t) blksz / 4 + 1))
{
- unsigned int perblock = blksz / 4;
- unsigned int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4
- * (blksz / 4 + 1));
+ int log_perblock = log2_blksz + 9 - 2;
+ grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4
+ * (blksz / 4 + 1));
grub_uint32_t indir[blksz / 4];
if (grub_disk_read (data->disk,
@@ -496,19 +498,19 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
if (grub_disk_read (data->disk,
((grub_disk_addr_t)
- grub_le_to_cpu32 (indir[(rblock / perblock) / perblock]))
+ grub_le_to_cpu32 (indir[(rblock >> log_perblock) >> log_perblock]))
<< log2_blksz,
0, blksz, indir))
return grub_errno;
if (grub_disk_read (data->disk,
((grub_disk_addr_t)
- grub_le_to_cpu32 (indir[(rblock / perblock) % perblock]))
+ grub_le_to_cpu32 (indir[(rblock >> log_perblock) & ((1 << log_perblock) - 1)]))
<< log2_blksz,
0, blksz, indir))
return grub_errno;
- blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
+ blknr = grub_le_to_cpu32 (indir[rblock & ((1 << log_perblock) - 1)]);
}
else
{
@@ -690,10 +692,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
static int
grub_ext2_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
unsigned int fpos = 0;
struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
@@ -775,7 +774,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir,
type = GRUB_FSHELP_REG;
}
- if (hook (filename, type, fdiro))
+ if (hook (filename, type, fdiro, hook_data))
return 1;
}
@@ -856,59 +855,69 @@ grub_ext2_read (grub_file_t file, char *buf, grub_size_t len)
}
-static grub_err_t
-grub_ext2_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+/* Context for grub_ext2_dir. */
+struct grub_ext2_dir_ctx
{
- struct grub_ext2_data *data = 0;
- struct grub_fshelp_node *fdiro = 0;
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+ struct grub_ext2_data *data;
+};
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
+/* Helper for grub_ext2_dir. */
+static int
+grub_ext2_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_ext2_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
+ grub_memset (&info, 0, sizeof (info));
+ if (! node->inode_read)
{
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- if (! node->inode_read)
- {
- grub_ext2_read_inode (data, node->ino, &node->inode);
- if (!grub_errno)
- node->inode_read = 1;
- grub_errno = GRUB_ERR_NONE;
- }
- if (node->inode_read)
- {
- info.mtimeset = 1;
- info.mtime = grub_le_to_cpu32 (node->inode.mtime);
- }
-
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- grub_free (node);
- return hook (filename, &info);
+ grub_ext2_read_inode (ctx->data, node->ino, &node->inode);
+ if (!grub_errno)
+ node->inode_read = 1;
+ grub_errno = GRUB_ERR_NONE;
}
+ if (node->inode_read)
+ {
+ info.mtimeset = 1;
+ info.mtime = grub_le_to_cpu32 (node->inode.mtime);
+ }
+
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
+static grub_err_t
+grub_ext2_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
+ void *hook_data)
+{
+ struct grub_ext2_dir_ctx ctx = {
+ .hook = hook,
+ .hook_data = hook_data
+ };
+ struct grub_fshelp_node *fdiro = 0;
grub_dl_ref (my_mod);
- data = grub_ext2_mount (device->disk);
- if (! data)
+ ctx.data = grub_ext2_mount (device->disk);
+ if (! ctx.data)
goto fail;
- grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir,
- grub_ext2_read_symlink, GRUB_FSHELP_DIR);
+ grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro,
+ grub_ext2_iterate_dir, grub_ext2_read_symlink,
+ GRUB_FSHELP_DIR);
if (grub_errno)
goto fail;
- grub_ext2_iterate_dir (fdiro, iterate);
+ grub_ext2_iterate_dir (fdiro, grub_ext2_dir_iter, &ctx);
fail:
- if (fdiro != &data->diropen)
+ if (fdiro != &ctx.data->diropen)
grub_free (fdiro);
- grub_free (data);
+ grub_free (ctx.data);
grub_dl_unref (my_mod);
diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c
index 119fc94..7664153 100644
--- a/grub-core/fs/fat.c
+++ b/grub-core/fs/fat.c
@@ -844,8 +844,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data,
static char *
grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
const char *path, const char *origpath,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
char *dirname, *dirp;
int call_hook;
@@ -905,7 +904,7 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
#endif
if (*dirname == '\0' && call_hook)
{
- if (hook (ctxt.filename, &info))
+ if (hook (ctxt.filename, &info, hook_data))
break;
else
continue;
@@ -926,7 +925,7 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
data->cur_cluster_num = ~0U;
if (call_hook)
- hook (ctxt.filename, &info);
+ hook (ctxt.filename, &info, hook_data);
break;
}
@@ -946,9 +945,8 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
}
static grub_err_t
-grub_fat_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
+ void *hook_data)
{
struct grub_fat_data *data = 0;
grub_disk_t disk = device->disk;
@@ -976,7 +974,7 @@ grub_fat_dir (grub_device_t device, const char *path,
do
{
- p = grub_fat_find_dir (disk, data, p, path, hook);
+ p = grub_fat_find_dir (disk, data, p, path, hook, hook_data);
}
while (p && grub_errno == GRUB_ERR_NONE);
@@ -1004,7 +1002,7 @@ grub_fat_open (grub_file_t file, const char *name)
do
{
- p = grub_fat_find_dir (file->device->disk, data, p, name, 0);
+ p = grub_fat_find_dir (file->device->disk, data, p, name, 0, 0);
if (grub_errno != GRUB_ERR_NONE)
goto fail;
}
diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c
index 21a72de..7e557c3 100644
--- a/grub-core/fs/fshelp.c
+++ b/grub-core/fs/fshelp.c
@@ -27,199 +27,214 @@
GRUB_MOD_LICENSE ("GPLv3+");
-/* Lookup the node PATH. The node ROOTNODE describes the root of the
- directory tree. The node found is returned in FOUNDNODE, which is
- either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
- iterate over all directory entries in the current node.
- READ_SYMLINK is used to read the symlink if a node is a symlink.
- EXPECTTYPE is the type node that is expected by the called, an
- error is generated if the node is not of the expected type. Make
- sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
- because GCC has a nasty bug when using regparm=3. */
-grub_err_t
-grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
- grub_fshelp_node_t *foundnode,
- int (*iterate_dir) (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR (*hook)
- (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)),
- char *(*read_symlink) (grub_fshelp_node_t node),
- enum grub_fshelp_filetype expecttype)
+typedef int (*iterate_dir_func) (grub_fshelp_node_t dir,
+ grub_fshelp_iterate_dir_hook_t hook,
+ void *data);
+typedef char *(*read_symlink_func) (grub_fshelp_node_t node);
+
+/* Context for grub_fshelp_find_file. */
+struct grub_fshelp_find_file_ctx
{
- grub_err_t err;
- enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR;
- int symlinknest = 0;
+ const char *path;
+ grub_fshelp_node_t rootnode, currroot, currnode, oldnode;
+ enum grub_fshelp_filetype foundtype;
+ int symlinknest;
+ char *name;
+ enum grub_fshelp_filetype type;
+};
+
+/* Helper for find_file_iter. */
+static void
+free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx)
+{
+ if (node != ctx->rootnode && node != ctx->currroot)
+ grub_free (node);
+}
- auto grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
- grub_fshelp_node_t currroot,
- grub_fshelp_node_t *currfound);
+/* Helper for grub_fshelp_find_file. */
+static int
+find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_fshelp_find_file_ctx *ctx = data;
- grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
- grub_fshelp_node_t currroot,
- grub_fshelp_node_t *currfound)
+ if (filetype == GRUB_FSHELP_UNKNOWN ||
+ (grub_strcmp (ctx->name, filename) &&
+ (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) ||
+ grub_strcasecmp (ctx->name, filename))))
{
- char fpath[grub_strlen (currpath) + 1];
- char *name = fpath;
- char *next;
- enum grub_fshelp_filetype type = GRUB_FSHELP_DIR;
- grub_fshelp_node_t currnode = currroot;
- grub_fshelp_node_t oldnode = currroot;
+ grub_free (node);
+ return 0;
+ }
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
+ /* The node is found, stop iterating over the nodes. */
+ ctx->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
+ ctx->oldnode = ctx->currnode;
+ ctx->currnode = node;
- auto void free_node (grub_fshelp_node_t node);
+ return 1;
+}
- void free_node (grub_fshelp_node_t node)
- {
- if (node != rootnode && node != currroot)
- grub_free (node);
- }
+static grub_err_t
+find_file (const char *currpath, grub_fshelp_node_t currroot,
+ grub_fshelp_node_t *currfound,
+ iterate_dir_func iterate_dir, read_symlink_func read_symlink,
+ struct grub_fshelp_find_file_ctx *ctx)
+{
+ char fpath[grub_strlen (currpath) + 1];
+ char *next;
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- if (filetype == GRUB_FSHELP_UNKNOWN ||
- (grub_strcmp (name, filename) &&
- (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) ||
- grub_strcasecmp (name, filename))))
- {
- grub_free (node);
- return 0;
- }
+ ctx->currroot = currroot;
+ ctx->name = fpath;
+ ctx->type = GRUB_FSHELP_DIR;
+ ctx->currnode = currroot;
+ ctx->oldnode = currroot;
- /* The node is found, stop iterating over the nodes. */
- type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
- oldnode = currnode;
- currnode = node;
+ grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1);
- return 1;
- }
+ /* Remove all leading slashes. */
+ while (*ctx->name == '/')
+ ctx->name++;
- grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1);
+ if (! *ctx->name)
+ {
+ *currfound = ctx->currnode;
+ return 0;
+ }
- /* Remove all leading slashes. */
- while (*name == '/')
- name++;
+ for (;;)
+ {
+ int found;
- if (! *name)
+ /* Extract the actual part from the pathname. */
+ next = grub_strchr (ctx->name, '/');
+ if (next)
{
- *currfound = currnode;
- return 0;
+ /* Remove all leading slashes. */
+ while (*next == '/')
+ *(next++) = '\0';
}
- for (;;)
+ /* At this point it is expected that the current node is a
+ directory, check if this is true. */
+ if (ctx->type != GRUB_FSHELP_DIR)
{
- int found;
+ free_node (ctx->currnode, ctx);
+ ctx->currnode = 0;
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
+ }
- /* Extract the actual part from the pathname. */
- next = grub_strchr (name, '/');
- if (next)
- {
- /* Remove all leading slashes. */
- while (*next == '/')
- *(next++) = '\0';
- }
+ /* Iterate over the directory. */
+ found = iterate_dir (ctx->currnode, find_file_iter, ctx);
+ if (! found)
+ {
+ free_node (ctx->currnode, ctx);
+ ctx->currnode = 0;
+ if (grub_errno)
+ return grub_errno;
+
+ break;
+ }
+
+ /* Read in the symlink and follow it. */
+ if (ctx->type == GRUB_FSHELP_SYMLINK)
+ {
+ char *symlink;
- /* At this point it is expected that the current node is a
- directory, check if this is true. */
- if (type != GRUB_FSHELP_DIR)
+ /* Test if the symlink does not loop. */
+ if (++ctx->symlinknest == 8)
{
- free_node (currnode);
- currnode = 0;
- return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
+ free_node (ctx->currnode, ctx);
+ free_node (ctx->oldnode, ctx);
+ ctx->currnode = 0;
+ return grub_error (GRUB_ERR_SYMLINK_LOOP,
+ N_("too deep nesting of symlinks"));
}
- /* Iterate over the directory. */
- found = iterate_dir (currnode, iterate);
- if (! found)
- {
- free_node (currnode);
- currnode = 0;
- if (grub_errno)
- return grub_errno;
+ symlink = read_symlink (ctx->currnode);
+ free_node (ctx->currnode, ctx);
+ ctx->currnode = 0;
- break;
+ if (!symlink)
+ {
+ free_node (ctx->oldnode, ctx);
+ return grub_errno;
}
- /* Read in the symlink and follow it. */
- if (type == GRUB_FSHELP_SYMLINK)
+ /* The symlink is an absolute path, go back to the root inode. */
+ if (symlink[0] == '/')
{
- char *symlink;
-
- /* Test if the symlink does not loop. */
- if (++symlinknest == 8)
- {
- free_node (currnode);
- free_node (oldnode);
- currnode = 0;
- return grub_error (GRUB_ERR_SYMLINK_LOOP,
- N_("too deep nesting of symlinks"));
- }
-
- symlink = read_symlink (currnode);
- free_node (currnode);
- currnode = 0;
-
- if (!symlink)
- {
- free_node (oldnode);
- return grub_errno;
- }
-
- /* The symlink is an absolute path, go back to the root inode. */
- if (symlink[0] == '/')
- {
- free_node (oldnode);
- oldnode = rootnode;
- }
-
- /* Lookup the node the symlink points to. */
- find_file (symlink, oldnode, &currnode);
- type = foundtype;
- grub_free (symlink);
-
- if (grub_errno)
- {
- free_node (oldnode);
- return grub_errno;
- }
+ free_node (ctx->oldnode, ctx);
+ ctx->oldnode = ctx->rootnode;
}
- if (oldnode != currnode)
- free_node (oldnode);
+ /* Lookup the node the symlink points to. */
+ find_file (symlink, ctx->oldnode, &ctx->currnode,
+ iterate_dir, read_symlink, ctx);
+ ctx->type = ctx->foundtype;
+ grub_free (symlink);
- /* Found the node! */
- if (! next || *next == '\0')
+ if (grub_errno)
{
- *currfound = currnode;
- foundtype = type;
- return 0;
+ free_node (ctx->oldnode, ctx);
+ return grub_errno;
}
+ }
+
+ if (ctx->oldnode != ctx->currnode)
+ free_node (ctx->oldnode, ctx);
- name = next;
+ /* Found the node! */
+ if (! next || *next == '\0')
+ {
+ *currfound = ctx->currnode;
+ ctx->foundtype = ctx->type;
+ return 0;
}
- return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
+ ctx->name = next;
}
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
+ ctx->path);
+}
+
+/* Lookup the node PATH. The node ROOTNODE describes the root of the
+ directory tree. The node found is returned in FOUNDNODE, which is
+ either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
+ iterate over all directory entries in the current node.
+ READ_SYMLINK is used to read the symlink if a node is a symlink.
+ EXPECTTYPE is the type node that is expected by the called, an
+ error is generated if the node is not of the expected type. */
+grub_err_t
+grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
+ grub_fshelp_node_t *foundnode,
+ iterate_dir_func iterate_dir,
+ read_symlink_func read_symlink,
+ enum grub_fshelp_filetype expecttype)
+{
+ struct grub_fshelp_find_file_ctx ctx = {
+ .path = path,
+ .rootnode = rootnode,
+ .foundtype = GRUB_FSHELP_DIR,
+ .symlinknest = 0
+ };
+ grub_err_t err;
+
if (!path || path[0] != '/')
{
grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path);
return grub_errno;
}
- err = find_file (path, rootnode, foundnode);
+ err = find_file (path, rootnode, foundnode, iterate_dir, read_symlink, &ctx);
if (err)
return err;
/* Check if the node that was found was of the expected type. */
- if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype)
+ if (expecttype == GRUB_FSHELP_REG && ctx.foundtype != expecttype)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
- else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype)
+ else if (expecttype == GRUB_FSHELP_DIR && ctx.foundtype != expecttype)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
return 0;
diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
index 0a249cc..9ed3330 100644
--- a/grub-core/fs/hfs.c
+++ b/grub-core/fs/hfs.c
@@ -1151,9 +1151,8 @@ grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
static grub_err_t
-grub_hfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
+ void *hook_data)
{
int inode;
@@ -1184,14 +1183,14 @@ grub_hfs_dir (grub_device_t device, const char *path,
info.dir = 1;
info.mtimeset = 1;
info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800;
- return hook (fname, &info);
+ return hook (fname, &info, hook_data);
}
if (frec->type == GRUB_HFS_FILETYPE_FILE)
{
info.dir = 0;
info.mtimeset = 1;
info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800;
- return hook (fname, &info);
+ return hook (fname, &info, hook_data);
}
return 0;
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
index 9812464..dcca581 100644
--- a/grub-core/fs/hfsplus.c
+++ b/grub-core/fs/hfsplus.c
@@ -766,10 +766,7 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
static int
grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
int ret = 0;
@@ -825,7 +822,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
node->size = 0;
node->fileid = grub_be_to_cpu32 (fileinfo->parentid);
- ret = hook ("..", GRUB_FSHELP_DIR, node);
+ ret = hook ("..", GRUB_FSHELP_DIR, node, hook_data);
return ret;
}
@@ -878,7 +875,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
node->size = grub_be_to_cpu64 (fileinfo->data.size);
node->fileid = grub_be_to_cpu32 (fileinfo->fileid);
- ret = hook (filename, type, node);
+ ret = hook (filename, type, node, hook_data);
grub_free (filename);
@@ -895,7 +892,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
if (!fsnode)
return 1;
*fsnode = *dir;
- if (hook (".", GRUB_FSHELP_DIR, fsnode))
+ if (hook (".", GRUB_FSHELP_DIR, fsnode, hook_data))
return 1;
}
@@ -978,32 +975,39 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
file->offset, len, buf);
}
+/* Context for grub_hfsplus_dir. */
+struct grub_hfsplus_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_hfsplus_dir. */
+static int
+grub_hfsplus_dir_iter (const char *filename,
+ enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_hfsplus_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ info.mtimeset = 1;
+ info.mtime = node->mtime;
+ info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
static grub_err_t
grub_hfsplus_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
+ struct grub_hfsplus_dir_ctx ctx = { hook, hook_data };
struct grub_hfsplus_data *data = 0;
struct grub_fshelp_node *fdiro = 0;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- info.mtimeset = 1;
- info.mtime = node->mtime;
- info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE);
- grub_free (node);
- return hook (filename, &info);
- }
-
grub_dl_ref (my_mod);
data = grub_hfsplus_mount (device->disk);
@@ -1018,7 +1022,7 @@ grub_hfsplus_dir (grub_device_t device, const char *path,
goto fail;
/* Iterate over all entries in this directory. */
- grub_hfsplus_iterate_dir (fdiro, iterate);
+ grub_hfsplus_iterate_dir (fdiro, grub_hfsplus_dir_iter, &ctx);
fail:
if (data && fdiro != &data->dirroot)
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
index cd4acc8..e37553d 100644
--- a/grub-core/fs/iso9660.c
+++ b/grub-core/fs/iso9660.c
@@ -295,7 +295,7 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off,
if (load_sua ())
return grub_errno;
- for (; (char *) entry < (char *) sua + sua_size - 1;
+ for (; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0;
entry = (struct grub_iso9660_susp_entry *)
((char *) entry + entry->len))
{
@@ -521,10 +521,7 @@ get_node_size (grub_fshelp_node_t node)
static int
grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
struct grub_iso9660_dir dirent;
grub_off_t offset = 0;
@@ -828,7 +825,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
symlink = 0;
was_continue = 0;
}
- if (hook (filename, type, node))
+ if (hook (filename, type, node, hook_data))
{
if (filename_alloc)
grub_free (filename);
@@ -844,32 +841,39 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
+/* Context for grub_iso9660_dir. */
+struct grub_iso9660_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_iso9660_dir. */
+static int
+grub_iso9660_dir_iter (const char *filename,
+ enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_iso9660_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime);
+
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
static grub_err_t
grub_iso9660_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
+ struct grub_iso9660_dir_ctx ctx = { hook, hook_data };
struct grub_iso9660_data *data = 0;
struct grub_fshelp_node rootnode;
struct grub_fshelp_node *foundnode;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime);
-
- grub_free (node);
- return hook (filename, &info);
- }
-
grub_dl_ref (my_mod);
data = grub_iso9660_mount (device->disk);
@@ -891,7 +895,7 @@ grub_iso9660_dir (grub_device_t device, const char *path,
goto fail;
/* List the files in the directory. */
- grub_iso9660_iterate_dir (foundnode, iterate);
+ grub_iso9660_iterate_dir (foundnode, grub_iso9660_dir_iter, &ctx);
if (foundnode != &rootnode)
grub_free (foundnode);
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
index b98a5a3..7c17192 100644
--- a/grub-core/fs/jfs.c
+++ b/grub-core/fs/jfs.c
@@ -799,8 +799,7 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino)
static grub_err_t
grub_jfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
struct grub_jfs_data *data = 0;
struct grub_jfs_diropen *diro = 0;
@@ -832,7 +831,7 @@ grub_jfs_dir (grub_device_t device, const char *path,
& GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR;
info.mtimeset = 1;
info.mtime = grub_le_to_cpu32 (inode.mtime.sec);
- if (hook (diro->name, &info))
+ if (hook (diro->name, &info, hook_data))
goto fail;
}
diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c
index 1e1c13b..9655211 100644
--- a/grub-core/fs/minix.c
+++ b/grub-core/fs/minix.c
@@ -261,12 +261,12 @@ grub_minix_read_file (struct grub_minix_data *data,
/* Adjust len so it we can't read past the end of the file. */
if (len + pos > GRUB_MINIX_INODE_SIZE (data))
len = GRUB_MINIX_INODE_SIZE (data) - pos;
+ if (len == 0)
+ return 0;
/* Files are at most 2G/4G - 1 bytes on minixfs. Avoid 64-bit division. */
- blockcnt = ((grub_uint32_t) ((len + pos
- + (data->block_size << GRUB_DISK_SECTOR_BITS)
- - 1)
- >> GRUB_DISK_SECTOR_BITS)) / data->block_size;
+ blockcnt = ((grub_uint32_t) ((len + pos - 1)
+ >> GRUB_DISK_SECTOR_BITS)) / data->block_size + 1;
posblock = (((grub_uint32_t) pos)
/ (data->block_size << GRUB_DISK_SECTOR_BITS));
blockoff = (((grub_uint32_t) pos)
@@ -536,8 +536,7 @@ grub_minix_mount (grub_disk_t disk)
static grub_err_t
grub_minix_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
struct grub_minix_data *data = 0;
unsigned int pos = 0;
@@ -590,7 +589,7 @@ grub_minix_dir (grub_device_t device, const char *path,
info.mtimeset = 1;
info.mtime = grub_minix_to_cpu32 (data->inode.mtime);
- if (hook (filename, &info) ? 1 : 0)
+ if (hook (filename, &info, hook_data) ? 1 : 0)
break;
/* Load the old inode back in. */
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
index f36c513..9bd4444 100644
--- a/grub-core/fs/nilfs2.c
+++ b/grub-core/fs/nilfs2.c
@@ -214,6 +214,8 @@ struct grub_nilfs2_palloc_group_desc
grub_uint32_t pg_nfrees;
};
+#define LOG_SIZE_GROUP_DESC 2
+
#define LOG_NILFS_DAT_ENTRY_SIZE 5
struct grub_nilfs2_dat_entry
{
@@ -311,10 +313,12 @@ grub_nilfs2_palloc_group (struct grub_nilfs2_data *data,
}
static inline grub_uint32_t
-grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data)
+grub_nilfs2_palloc_log_groups_per_desc_block (struct grub_nilfs2_data *data)
{
- return NILFS2_BLOCK_SIZE (data) /
- sizeof (struct grub_nilfs2_palloc_group_desc);
+ return LOG2_BLOCK_SIZE (data) - LOG_SIZE_GROUP_DESC;
+
+ COMPILE_TIME_ASSERT (sizeof (struct grub_nilfs2_palloc_group_desc)
+ == (1 << LOG_SIZE_GROUP_DESC));
}
static inline grub_uint32_t
@@ -338,8 +342,8 @@ static inline grub_uint32_t
grub_nilfs2_blocks_per_desc_block_log (struct grub_nilfs2_data *data,
unsigned long log_entry_size)
{
- return grub_nilfs2_palloc_groups_per_desc_block (data) *
- grub_nilfs2_blocks_per_group_log (data, log_entry_size) + 1;
+ return(grub_nilfs2_blocks_per_group_log (data, log_entry_size)
+ << grub_nilfs2_palloc_log_groups_per_desc_block (data)) + 1;
}
static inline grub_uint32_t
@@ -348,7 +352,7 @@ grub_nilfs2_palloc_desc_block_offset_log (struct grub_nilfs2_data *data,
unsigned long log_entry_size)
{
grub_uint32_t desc_block =
- group / grub_nilfs2_palloc_groups_per_desc_block (data);
+ group >> grub_nilfs2_palloc_log_groups_per_desc_block (data);
return desc_block * grub_nilfs2_blocks_per_desc_block_log (data,
log_entry_size);
}
@@ -358,8 +362,8 @@ grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data,
unsigned long group,
unsigned long log_entry_size)
{
- unsigned long desc_offset = group %
- grub_nilfs2_palloc_groups_per_desc_block (data);
+ unsigned long desc_offset = group
+ & ((1 << grub_nilfs2_palloc_log_groups_per_desc_block (data)) - 1);
return grub_nilfs2_palloc_desc_block_offset_log (data, group, log_entry_size)
+ 1
@@ -866,10 +870,7 @@ grub_nilfs2_read_symlink (grub_fshelp_node_t node)
static int
grub_nilfs2_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
grub_off_t fpos = 0;
struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
@@ -953,7 +954,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir,
type = GRUB_FSHELP_REG;
}
- if (hook (filename, type, fdiro))
+ if (hook (filename, type, fdiro, hook_data))
return 1;
}
@@ -1028,60 +1029,69 @@ grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len)
file->offset, len, buf);
}
+/* Context for grub_nilfs2_dir. */
+struct grub_nilfs2_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+ struct grub_nilfs2_data *data;
+};
+
+/* Helper for grub_nilfs2_dir. */
+static int
+grub_nilfs2_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_nilfs2_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+ if (!node->inode_read)
+ {
+ grub_nilfs2_read_inode (ctx->data, node->ino, &node->inode);
+ if (!grub_errno)
+ node->inode_read = 1;
+ grub_errno = GRUB_ERR_NONE;
+ }
+ if (node->inode_read)
+ {
+ info.mtimeset = 1;
+ info.mtime = grub_le_to_cpu64 (node->inode.i_mtime);
+ }
+
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
static grub_err_t
grub_nilfs2_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info * info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
- struct grub_nilfs2_data *data = 0;
+ struct grub_nilfs2_dir_ctx ctx = {
+ .hook = hook,
+ .hook_data = hook_data
+ };
struct grub_fshelp_node *fdiro = 0;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- if (!node->inode_read)
- {
- grub_nilfs2_read_inode (data, node->ino, &node->inode);
- if (!grub_errno)
- node->inode_read = 1;
- grub_errno = GRUB_ERR_NONE;
- }
- if (node->inode_read)
- {
- info.mtimeset = 1;
- info.mtime = grub_le_to_cpu64 (node->inode.i_mtime);
- }
-
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- grub_free (node);
- return hook (filename, &info);
- }
-
grub_dl_ref (my_mod);
- data = grub_nilfs2_mount (device->disk);
- if (!data)
+ ctx.data = grub_nilfs2_mount (device->disk);
+ if (!ctx.data)
goto fail;
- grub_fshelp_find_file (path, &data->diropen, &fdiro,
+ grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro,
grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink,
GRUB_FSHELP_DIR);
if (grub_errno)
goto fail;
- grub_nilfs2_iterate_dir (fdiro, iterate);
+ grub_nilfs2_iterate_dir (fdiro, grub_nilfs2_dir_iter, &ctx);
fail:
- if (fdiro != &data->diropen)
+ if (fdiro != &ctx.data->diropen)
grub_free (fdiro);
- grub_free (data);
+ grub_free (ctx.data);
grub_dl_unref (my_mod);
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index b9762b6..7ac46f9 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -55,10 +55,10 @@ u64at (void *ptr, grub_size_t ofs)
grub_ntfscomp_func_t grub_ntfscomp_func;
static grub_err_t
-fixup (char *buf, int len, const char *magic)
+fixup (grub_uint8_t *buf, grub_size_t len, const grub_uint8_t *magic)
{
- int ss;
- char *pu;
+ grub_uint16_t ss;
+ grub_uint8_t *pu;
grub_uint16_t us;
COMPILE_TIME_ASSERT ((1 << GRUB_NTFS_BLK_SHR) == GRUB_DISK_SECTOR_SIZE);
@@ -86,9 +86,9 @@ fixup (char *buf, int len, const char *magic)
return 0;
}
-static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf,
+static grub_err_t read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf,
grub_uint32_t mftno);
-static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
+static grub_err_t read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest,
grub_disk_addr_t ofs, grub_size_t len,
int cached,
void
@@ -97,7 +97,8 @@ static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
unsigned offset,
unsigned length));
-static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
+static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa,
+ grub_uint8_t *dest,
grub_disk_addr_t ofs, grub_size_t len,
int cached,
void
@@ -123,8 +124,8 @@ free_attr (struct grub_ntfs_attr *at)
grub_free (at->sbuf);
}
-static char *
-find_attr (struct grub_ntfs_attr *at, unsigned char attr)
+static grub_uint8_t *
+find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
{
if (at->flags & GRUB_NTFS_AF_ALST)
{
@@ -133,9 +134,9 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
{
at->attr_cur = at->attr_nxt;
at->attr_nxt += u16at (at->attr_cur, 4);
- if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
+ if ((*at->attr_cur == attr) || (attr == 0))
{
- char *new_pos;
+ grub_uint8_t *new_pos;
if (at->flags & GRUB_NTFS_AF_MMFT)
{
@@ -148,7 +149,8 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
512, at->emft_buf + 512)))
return NULL;
- if (fixup (at->emft_buf, at->mft->data->mft_size, "FILE"))
+ if (fixup (at->emft_buf, at->mft->data->mft_size,
+ (const grub_uint8_t *) "FILE"))
return NULL;
}
else
@@ -159,10 +161,9 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
}
new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)];
- while ((unsigned char) *new_pos != 0xFF)
+ while (*new_pos != 0xFF)
{
- if (((unsigned char) *new_pos ==
- (unsigned char) *at->attr_cur)
+ if ((*new_pos == *at->attr_cur)
&& (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18)))
{
return new_pos;
@@ -178,18 +179,18 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
return NULL;
}
at->attr_cur = at->attr_nxt;
- while ((unsigned char) *at->attr_cur != 0xFF)
+ while (*at->attr_cur != 0xFF)
{
at->attr_nxt += u16at (at->attr_cur, 4);
- if ((unsigned char) *at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST)
+ if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST)
at->attr_end = at->attr_cur;
- if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
+ if ((*at->attr_cur == attr) || (attr == 0))
return at->attr_cur;
at->attr_cur = at->attr_nxt;
}
if (at->attr_end)
{
- char *pa;
+ grub_uint8_t *pa;
at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
if (at->emft_buf == NULL)
@@ -198,7 +199,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
pa = at->attr_end;
if (pa[8])
{
- int n;
+ grub_uint32_t n;
n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1)
& (~(GRUB_DISK_SECTOR_SIZE - 1)));
@@ -223,7 +224,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
at->flags |= GRUB_NTFS_AF_ALST;
while (at->attr_nxt < at->attr_end)
{
- if (((unsigned char) *at->attr_nxt == attr) || (attr == 0))
+ if ((*at->attr_nxt == attr) || (attr == 0))
break;
at->attr_nxt += u16at (at->attr_nxt, 4);
}
@@ -243,7 +244,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
pa = at->attr_nxt + u16at (pa, 4);
while (pa < at->attr_end)
{
- if ((unsigned char) *pa != attr)
+ if (*pa != attr)
break;
if (read_attr
(at, pa + 0x10,
@@ -260,11 +261,11 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
return NULL;
}
-static char *
+static grub_uint8_t *
locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
- unsigned char attr)
+ grub_uint8_t attr)
{
- char *pa;
+ grub_uint8_t *pa;
init_attr (at, mft);
pa = find_attr (at, attr);
@@ -288,8 +289,8 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
return pa;
}
-static char *
-read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig)
+static grub_uint8_t *
+read_run_data (grub_uint8_t *run, int nn, grub_disk_addr_t * val, int sig)
{
grub_disk_addr_t r, v;
@@ -298,7 +299,7 @@ read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig)
while (nn--)
{
- r += v * (*(unsigned char *) (run++));
+ r += v * (*(run++));
v <<= 8;
}
@@ -312,14 +313,14 @@ read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig)
grub_err_t
grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
{
- int c1, c2;
+ grub_uint8_t c1, c2;
grub_disk_addr_t val;
- char *run;
+ grub_uint8_t *run;
run = ctx->cur_run;
retry:
- c1 = ((unsigned char) (*run) & 0xF);
- c2 = ((unsigned char) (*run) >> 4);
+ c1 = ((*run) & 0xF);
+ c2 = ((*run) >> 4);
if (!c1)
{
if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST))
@@ -330,7 +331,7 @@ retry:
save_hook = ctx->comp.disk->read_hook;
ctx->comp.disk->read_hook = 0;
- run = find_attr (ctx->attr, (unsigned char) *ctx->attr->attr_cur);
+ run = find_attr (ctx->attr, *ctx->attr->attr_cur);
ctx->comp.disk->read_hook = save_hook;
if (run)
{
@@ -376,7 +377,7 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
}
static grub_err_t
-read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
+read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
grub_disk_addr_t ofs, grub_size_t len, int cached,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
unsigned offset,
@@ -391,7 +392,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
grub_memset (&cc, 0, sizeof (cc));
ctx = &cc;
ctx->attr = at;
- ctx->comp.spc = at->mft->data->spc;
+ ctx->comp.log_spc = at->mft->data->log_spc;
ctx->comp.disk = at->mft->data->disk;
if (pa[8] == 0)
@@ -440,11 +441,11 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
at->save_pos = 1;
}
- vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC / ctx->comp.spc);
+ vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC >> ctx->comp.log_spc);
ctx->target_vcn &= ~0xFULL;
}
else
- vcn = ctx->target_vcn = grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, 0);
+ vcn = ctx->target_vcn = ofs >> (GRUB_NTFS_BLK_SHR + ctx->comp.log_spc);
ctx->next_vcn = u32at (pa, 0x10);
ctx->curr_lcn = 0;
@@ -459,17 +460,17 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
grub_disk_addr_t st0, st1;
grub_uint64_t m;
- grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, &m);
+ m = (ofs >> GRUB_NTFS_BLK_SHR) & ((1 << ctx->comp.log_spc) - 1);
st0 =
- (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
+ ((ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) << ctx->comp.log_spc) + m;
st1 = st0 + 1;
if (st1 ==
- (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
+ (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) << ctx->comp.log_spc)
{
if (grub_ntfs_read_run_list (ctx))
return grub_errno;
- st1 = ctx->curr_lcn * ctx->comp.spc;
+ st1 = ctx->curr_lcn << ctx->comp.log_spc;
}
grub_set_unaligned32 (dest, grub_cpu_to_le32 (st0));
grub_set_unaligned32 (dest + 4, grub_cpu_to_le32 (st1));
@@ -478,12 +479,10 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
if (!(ctx->flags & GRUB_NTFS_RF_COMP))
{
- unsigned int pow;
-
- if (!grub_fshelp_log2blksize (ctx->comp.spc, &pow))
- grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx,
- read_hook, ofs, len, dest,
- grub_ntfs_read_block, ofs + len, pow, 0);
+ grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx,
+ read_hook, ofs, len, (char *) dest,
+ grub_ntfs_read_block, ofs + len,
+ ctx->comp.log_spc, 0);
return grub_errno;
}
@@ -494,36 +493,36 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
}
static grub_err_t
-read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
+read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
grub_size_t len, int cached,
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
unsigned offset,
unsigned length))
{
- char *save_cur;
- unsigned char attr;
- char *pp;
+ grub_uint8_t *save_cur;
+ grub_uint8_t attr;
+ grub_uint8_t *pp;
grub_err_t ret;
save_cur = at->attr_cur;
at->attr_nxt = at->attr_cur;
- attr = (unsigned char) *at->attr_nxt;
+ attr = *at->attr_nxt;
if (at->flags & GRUB_NTFS_AF_ALST)
{
- char *pa;
+ grub_uint8_t *pa;
grub_disk_addr_t vcn;
/* If compression is possible make sure that we include possible
compressed block size. */
- if (GRUB_NTFS_COM_SEC >= at->mft->data->spc)
+ if (GRUB_NTFS_LOG_COM_SEC >= at->mft->data->log_spc)
vcn = ((ofs >> GRUB_NTFS_COM_LOG_LEN)
- * (GRUB_NTFS_COM_SEC / at->mft->data->spc)) & ~0xFULL;
+ << (GRUB_NTFS_LOG_COM_SEC - at->mft->data->log_spc)) & ~0xFULL;
else
- vcn = grub_divmod64 (ofs, at->mft->data->spc << GRUB_NTFS_BLK_SHR, 0);
+ vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR);
pa = at->attr_nxt + u16at (at->attr_nxt, 4);
while (pa < at->attr_end)
{
- if ((unsigned char) *pa != attr)
+ if (*pa != attr)
break;
if (u32at (pa, 8) > vcn)
break;
@@ -543,13 +542,13 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
}
static grub_err_t
-read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
+read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, grub_uint32_t mftno)
{
if (read_attr
(&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR),
data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0))
return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno);
- return fixup (buf, data->mft_size, "FILE");
+ return fixup (buf, data->mft_size, (const grub_uint8_t *) "FILE");
}
static grub_err_t
@@ -572,7 +571,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno)
if ((flag & 2) == 0)
{
- char *pa;
+ grub_uint8_t *pa;
pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_DATA);
if (pa == NULL)
@@ -600,24 +599,22 @@ free_file (struct grub_ntfs_file *mft)
}
static int
-list_file (struct grub_ntfs_file *diro, char *pos,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
- char *np;
+ grub_uint8_t *np;
int ns;
while (1)
{
- char *ustr, namespace;
+ grub_uint8_t namespace;
+ char *ustr;
if (pos[0xC] & 2) /* end signature */
break;
np = pos + 0x50;
- ns = (unsigned char) *(np++);
+ ns = *(np++);
namespace = *(np++);
/*
@@ -667,7 +664,7 @@ list_file (struct grub_ntfs_file *diro, char *pos,
if (namespace)
type |= GRUB_FSHELP_CASE_INSENSITIVE;
- if (hook (ustr, type, fdiro))
+ if (hook (ustr, type, fdiro, hook_data))
{
grub_free (ustr);
return 1;
@@ -700,7 +697,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node)
char *buf, *end;
grub_size_t len;
grub_size_t i;
- char *pa;
+ grub_uint8_t *pa;
grub_size_t off;
mft = (struct grub_ntfs_file *) node;
@@ -719,7 +716,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node)
return NULL;
}
- err = read_attr (&mft->attr, (char *) &symdesc, 0,
+ err = read_attr (&mft->attr, (grub_uint8_t *) &symdesc, 0,
sizeof (struct symlink_descriptor), 1, 0);
if (err)
return NULL;
@@ -746,7 +743,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node)
if (!buf16)
return NULL;
- err = read_attr (&mft->attr, (char *) buf16, off, len, 1, 0);
+ err = read_attr (&mft->attr, (grub_uint8_t *) buf16, off, len, 1, 0);
if (err)
return NULL;
@@ -778,14 +775,11 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node)
static int
grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
- unsigned char *bitmap;
+ grub_uint8_t *bitmap;
struct grub_ntfs_attr attr, *at;
- char *cur_pos, *indx, *bmp;
+ grub_uint8_t *cur_pos, *indx, *bmp;
int ret = 0;
grub_size_t bitmap_len;
struct grub_ntfs_file *mft;
@@ -824,7 +818,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
}
cur_pos += 0x10; /* Skip index root */
- ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook);
+ ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, hook_data);
if (ret)
goto done;
@@ -836,7 +830,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
{
int ofs;
- ofs = (unsigned char) cur_pos[0xA];
+ ofs = cur_pos[0xA];
/* Namelen=4, Name="$I30" */
if ((cur_pos[9] == 4) &&
(u32at (cur_pos, ofs) == 0x490024) &&
@@ -853,7 +847,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
if (is_resident)
{
- grub_memcpy (bmp, (char *) (cur_pos + u16at (cur_pos, 0x14)),
+ grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14),
bitmap_len);
}
else
@@ -867,7 +861,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
bitmap_len = u32at (cur_pos, 0x30);
}
- bitmap = (unsigned char *) bmp;
+ bitmap = bmp;
break;
}
}
@@ -906,9 +900,11 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
if ((read_attr
(at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR),
(mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0))
- || (fixup (indx, mft->data->idx_size, "INDX")))
+ || (fixup (indx, mft->data->idx_size,
+ (const grub_uint8_t *) "INDX")))
goto done;
- ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook);
+ ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)],
+ hook, hook_data);
if (ret)
goto done;
}
@@ -934,6 +930,7 @@ grub_ntfs_mount (grub_disk_t disk)
{
struct grub_ntfs_bpb bpb;
struct grub_ntfs_data *data = 0;
+ grub_uint32_t spc;
if (!disk)
goto fail;
@@ -955,23 +952,26 @@ grub_ntfs_mount (grub_disk_t disk)
|| (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0)
goto fail;
- data->spc = (((grub_uint32_t) bpb.sectors_per_cluster
- * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector))
- >> GRUB_NTFS_BLK_SHR);
- if (!data->spc)
+ spc = (((grub_uint32_t) bpb.sectors_per_cluster
+ * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector))
+ >> GRUB_NTFS_BLK_SHR);
+ if (spc == 0 || (spc & (spc - 1)))
goto fail;
+ for (data->log_spc = 0; (1U << data->log_spc) < spc; data->log_spc++);
+
if (bpb.clusters_per_mft > 0)
- data->mft_size = data->spc * bpb.clusters_per_mft;
+ data->mft_size = ((grub_disk_addr_t) bpb.clusters_per_mft) << data->log_spc;
else
- data->mft_size = 1 << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR);
+ data->mft_size = 1ULL << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR);
if (bpb.clusters_per_index > 0)
- data->idx_size = data->spc * bpb.clusters_per_index;
+ data->idx_size = (((grub_disk_addr_t) bpb.clusters_per_index)
+ << data->log_spc);
else
- data->idx_size = 1 << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR);
+ data->idx_size = 1ULL << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR);
- data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc;
+ data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) << data->log_spc;
if ((data->mft_size > GRUB_NTFS_MAX_MFT) || (data->idx_size > GRUB_NTFS_MAX_IDX))
goto fail;
@@ -989,7 +989,7 @@ grub_ntfs_mount (grub_disk_t disk)
data->uuid = grub_le_to_cpu64 (bpb.num_serial);
- if (fixup (data->mmft.buf, data->mft_size, "FILE"))
+ if (fixup (data->mmft.buf, data->mft_size, (const grub_uint8_t *) "FILE"))
goto fail;
if (!locate_attr (&data->mmft.attr, &data->mmft, GRUB_NTFS_AT_DATA))
@@ -1012,33 +1012,39 @@ fail:
return 0;
}
+/* Context for grub_ntfs_dir. */
+struct grub_ntfs_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_ntfs_dir. */
+static int
+grub_ntfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_ntfs_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ info.mtimeset = 1;
+ info.mtime = grub_divmod64 (node->mtime, 10000000, 0)
+ - 86400ULL * 365 * (1970 - 1601)
+ - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
static grub_err_t
grub_ntfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
+ struct grub_ntfs_dir_ctx ctx = { hook, hook_data };
struct grub_ntfs_data *data = 0;
struct grub_fshelp_node *fdiro = 0;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- info.mtimeset = 1;
- info.mtime = grub_divmod64 (node->mtime, 10000000, 0)
- - 86400ULL * 365 * (1970 - 1601)
- - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100);
- grub_free (node);
- return hook (filename, &info);
- }
-
grub_dl_ref (my_mod);
data = grub_ntfs_mount (device->disk);
@@ -1051,7 +1057,7 @@ grub_ntfs_dir (grub_device_t device, const char *path,
if (grub_errno)
goto fail;
- grub_ntfs_iterate_dir (fdiro, iterate);
+ grub_ntfs_iterate_dir (fdiro, grub_ntfs_dir_iter, &ctx);
fail:
if ((fdiro) && (fdiro != &data->cmft))
@@ -1129,7 +1135,8 @@ grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len)
if (file->read_hook)
mft->attr.save_pos = 1;
- read_attr (&mft->attr, buf, file->offset, len, 1, file->read_hook);
+ read_attr (&mft->attr, (grub_uint8_t *) buf, file->offset, len, 1,
+ file->read_hook);
return (grub_errno) ? -1 : (grub_ssize_t) len;
}
@@ -1157,7 +1164,7 @@ grub_ntfs_label (grub_device_t device, char **label)
{
struct grub_ntfs_data *data = 0;
struct grub_fshelp_node *mft = 0;
- char *pa;
+ grub_uint8_t *pa;
grub_dl_ref (my_mod);
@@ -1187,7 +1194,7 @@ grub_ntfs_label (grub_device_t device, char **label)
pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME);
if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
{
- char *buf;
+ grub_uint8_t *buf;
int len;
len = u32at (pa, 0x10) / 2;
@@ -1198,10 +1205,9 @@ grub_ntfs_label (grub_device_t device, char **label)
int i;
for (i = 0; i < len; i++)
tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 (pa + 2 * i));
- *grub_utf16_to_utf8 ((grub_uint8_t *) buf, tmp, len) =
- '\0';
+ *grub_utf16_to_utf8 (buf, tmp, len) = '\0';
}
- *label = buf;
+ *label = (char *) buf;
}
fail:
diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c
index ec359fa..02ea9fd 100644
--- a/grub-core/fs/ntfscomp.c
+++ b/grub-core/fs/ntfscomp.c
@@ -33,8 +33,9 @@ decomp_nextvcn (struct grub_ntfs_comp *cc)
if (grub_disk_read
(cc->disk,
(cc->comp_table[cc->comp_head].next_lcn -
- (cc->comp_table[cc->comp_head].next_vcn - cc->cbuf_vcn)) * cc->spc, 0,
- cc->spc << GRUB_NTFS_BLK_SHR, cc->cbuf))
+ (cc->comp_table[cc->comp_head].next_vcn - cc->cbuf_vcn)) << cc->log_spc,
+ 0,
+ 1 << (cc->log_spc + GRUB_NTFS_BLK_SHR), cc->cbuf))
return grub_errno;
cc->cbuf_vcn++;
if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head].next_vcn))
@@ -44,21 +45,21 @@ decomp_nextvcn (struct grub_ntfs_comp *cc)
}
static grub_err_t
-decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res)
+decomp_getch (struct grub_ntfs_comp *cc, grub_uint8_t *res)
{
- if (cc->cbuf_ofs >= (cc->spc << GRUB_NTFS_BLK_SHR))
+ if (cc->cbuf_ofs >= (1U << (cc->log_spc + GRUB_NTFS_BLK_SHR)))
{
if (decomp_nextvcn (cc))
return grub_errno;
}
- *res = (unsigned char) cc->cbuf[cc->cbuf_ofs++];
+ *res = cc->cbuf[cc->cbuf_ofs++];
return 0;
}
static grub_err_t
decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res)
{
- unsigned char c1 = 0, c2 = 0;
+ grub_uint8_t c1 = 0, c2 = 0;
if ((decomp_getch (cc, &c1)) || (decomp_getch (cc, &c2)))
return grub_errno;
@@ -68,7 +69,7 @@ decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res)
/* Decompress a block (4096 bytes) */
static grub_err_t
-decomp_block (struct grub_ntfs_comp *cc, char *dest)
+decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest)
{
grub_uint16_t flg, cnt;
@@ -80,7 +81,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest)
{
if (flg & 0x8000)
{
- unsigned char tag;
+ grub_uint8_t tag;
grub_uint32_t bits, copied;
bits = copied = tag = 0;
@@ -135,7 +136,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest)
}
else
{
- unsigned char ch = 0;
+ grub_uint8_t ch = 0;
if (decomp_getch (cc, &ch))
return grub_errno;
@@ -159,7 +160,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest)
{
int n;
- n = (cc->spc << GRUB_NTFS_BLK_SHR) - cc->cbuf_ofs;
+ n = (1 << (cc->log_spc + GRUB_NTFS_BLK_SHR)) - cc->cbuf_ofs;
if (n > cnt)
n = cnt;
if ((dest) && (n))
@@ -176,9 +177,9 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest)
}
static grub_err_t
-read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num)
+read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num)
{
- int cpb = GRUB_NTFS_COM_SEC / ctx->comp.spc;
+ int log_cpb = GRUB_NTFS_LOG_COM_SEC - ctx->comp.log_spc;
while (num)
{
@@ -192,7 +193,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num)
return grub_error (GRUB_ERR_BAD_FS, "invalid compression block");
ctx->comp.comp_head = ctx->comp.comp_tail = 0;
ctx->comp.cbuf_vcn = ctx->target_vcn;
- ctx->comp.cbuf_ofs = (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
+ ctx->comp.cbuf_ofs = (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR));
if (ctx->target_vcn >= ctx->next_vcn)
{
if (grub_ntfs_read_run_list (ctx))
@@ -211,14 +212,14 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num)
}
}
- nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) / cpb;
+ nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) >> log_cpb;
if (nn > num)
nn = num;
num -= nn;
if (ctx->flags & GRUB_NTFS_RF_BLNK)
{
- ctx->target_vcn += nn * cpb;
+ ctx->target_vcn += nn << log_cpb;
if (ctx->comp.comp_tail == 0)
{
if (buf)
@@ -241,7 +242,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num)
}
else
{
- nn *= cpb;
+ nn <<= log_cpb;
while ((ctx->comp.comp_head < ctx->comp.comp_tail) && (nn))
{
grub_disk_addr_t tt;
@@ -258,10 +259,10 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num)
(ctx->comp.disk,
(ctx->comp.comp_table[ctx->comp.comp_head].next_lcn -
(ctx->comp.comp_table[ctx->comp.comp_head].next_vcn -
- ctx->target_vcn)) * ctx->comp.spc, 0,
- tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf))
+ ctx->target_vcn)) << ctx->comp.log_spc, 0,
+ tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR), buf))
return grub_errno;
- buf += tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
+ buf += tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR);
}
nn -= tt;
if (ctx->target_vcn >=
@@ -275,10 +276,10 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num)
if (grub_disk_read
(ctx->comp.disk,
(ctx->target_vcn - ctx->curr_vcn +
- ctx->curr_lcn) * ctx->comp.spc, 0,
- nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf))
+ ctx->curr_lcn) << ctx->comp.log_spc, 0,
+ nn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR), buf))
return grub_errno;
- buf += nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
+ buf += nn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR);
}
ctx->target_vcn += nn;
}
@@ -288,13 +289,13 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num)
}
static grub_err_t
-ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
+ntfscomp (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
grub_size_t len, struct grub_ntfs_rlst *ctx, grub_disk_addr_t vcn)
{
grub_err_t ret;
ctx->comp.comp_head = ctx->comp.comp_tail = 0;
- ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << GRUB_NTFS_BLK_SHR);
+ ctx->comp.cbuf = grub_malloc (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR));
if (!ctx->comp.cbuf)
return 0;
@@ -304,7 +305,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
if ((vcn > ctx->target_vcn) &&
(read_block
- (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / GRUB_NTFS_COM_SEC)))
+ (ctx, NULL, (vcn - ctx->target_vcn) >> (GRUB_NTFS_LOG_COM_SEC - ctx->comp.log_spc))))
{
ret = grub_errno;
goto quit;
@@ -314,7 +315,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
{
grub_uint32_t t, n, o;
- t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
+ t = ctx->target_vcn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR);
if (read_block (ctx, at->sbuf, 1))
{
ret = grub_errno;
@@ -346,7 +347,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
{
grub_uint32_t t;
- t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR);
+ t = ctx->target_vcn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR);
if (read_block (ctx, at->sbuf, 1))
{
ret = grub_errno;
diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c
index 26adf23..686e4da 100644
--- a/grub-core/fs/reiserfs.c
+++ b/grub-core/fs/reiserfs.c
@@ -718,10 +718,8 @@ grub_reiserfs_mount (grub_disk_t disk)
/* Call HOOK for each file in directory ITEM. */
static int
grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook,
+ void *hook_data)
{
struct grub_reiserfs_data *data = item->data;
struct grub_reiserfs_block_header *block_header = 0;
@@ -946,7 +944,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
goto next;
}
}
- if (hook (entry_name, entry_type, entry_item))
+ if (hook (entry_name, entry_type, entry_item, hook_data))
{
grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
entry_name, entry_type);
@@ -1254,32 +1252,40 @@ grub_reiserfs_close (grub_file_t file)
return GRUB_ERR_NONE;
}
+/* Context for grub_reiserfs_dir. */
+struct grub_reiserfs_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_reiserfs_dir. */
+static int
+grub_reiserfs_dir_iter (const char *filename,
+ enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_reiserfs_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ info.mtimeset = 1;
+ info.mtime = node->mtime;
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
/* Call HOOK with each file under DIR. */
static grub_err_t
grub_reiserfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
+ struct grub_reiserfs_dir_ctx ctx = { hook, hook_data };
struct grub_reiserfs_data *data = 0;
struct grub_fshelp_node root, *found;
struct grub_reiserfs_key root_key;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- info.mtimeset = 1;
- info.mtime = node->mtime;
- grub_free (node);
- return hook (filename, &info);
- }
grub_dl_ref (my_mod);
data = grub_reiserfs_mount (device->disk);
if (! data)
@@ -1300,7 +1306,7 @@ grub_reiserfs_dir (grub_device_t device, const char *path,
grub_reiserfs_read_symlink, GRUB_FSHELP_DIR);
if (grub_errno)
goto fail;
- grub_reiserfs_iterate_dir (found, iterate);
+ grub_reiserfs_iterate_dir (found, grub_reiserfs_dir_iter, &ctx);
grub_free (data);
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c
index b30caef..b79b1e1 100644
--- a/grub-core/fs/romfs.c
+++ b/grub-core/fs/romfs.c
@@ -171,10 +171,7 @@ grub_romfs_read_symlink (grub_fshelp_node_t node)
static int
grub_romfs_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
grub_disk_addr_t caddr;
struct grub_romfs_file_header hdr;
@@ -306,7 +303,7 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir,
}
}
- if (hook ((char *) name, filetype, node))
+ if (hook ((char *) name, filetype, node, hook_data))
{
grub_free (name);
return 1;
@@ -316,30 +313,36 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir,
return 0;
}
+/* Context for grub_romfs_dir. */
+struct grub_romfs_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_romfs_dir. */
+static int
+grub_romfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_romfs_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
static grub_err_t
grub_romfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
+ struct grub_romfs_dir_ctx ctx = { hook, hook_data };
struct grub_romfs_data *data = 0;
struct grub_fshelp_node *fdiro = 0, start;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
-
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- grub_free (node);
- return hook (filename, &info);
- }
-
data = grub_romfs_mount (device);
if (! data)
goto fail;
@@ -352,7 +355,7 @@ grub_romfs_dir (grub_device_t device, const char *path,
if (grub_errno)
goto fail;
- grub_romfs_iterate_dir (fdiro, iterate);
+ grub_romfs_iterate_dir (fdiro, grub_romfs_dir_iter, &ctx);
fail:
grub_free (data);
diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
index f7cdb08..fed17d3 100644
--- a/grub-core/fs/sfs.c
+++ b/grub-core/fs/sfs.c
@@ -460,12 +460,48 @@ grub_sfs_read_symlink (grub_fshelp_node_t node)
return symlink;
}
+/* Helper for grub_sfs_iterate_dir. */
+static int
+grub_sfs_create_node (struct grub_fshelp_node **node,
+ struct grub_sfs_data *data,
+ const char *name,
+ grub_uint32_t block, grub_uint32_t size, int type,
+ grub_uint32_t mtime,
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
+{
+ grub_size_t len = grub_strlen (name);
+ grub_uint8_t *name_u8;
+ int ret;
+ *node = grub_malloc (sizeof (**node));
+ if (!*node)
+ return 1;
+ name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
+ if (!name_u8)
+ {
+ grub_free (*node);
+ return 1;
+ }
+
+ (*node)->data = data;
+ (*node)->size = size;
+ (*node)->block = block;
+ (*node)->mtime = mtime;
+ (*node)->cache = 0;
+ (*node)->cache_off = 0;
+ (*node)->next_extent = block;
+ (*node)->cache_size = 0;
+ (*node)->cache_allocated = 0;
+
+ *grub_latin1_to_utf8 (name_u8, (const grub_uint8_t *) name, len) = '\0';
+
+ ret = hook ((char *) name_u8, type | data->fshelp_flags, *node, hook_data);
+ grub_free (name_u8);
+ return ret;
+}
+
static int
grub_sfs_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
struct grub_fshelp_node *node = 0;
struct grub_sfs_data *data = dir->data;
@@ -474,46 +510,6 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
unsigned int next = dir->block;
grub_uint32_t pos;
- auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name,
- grub_uint32_t block,
- grub_uint32_t size, int type,
- grub_uint32_t mtime);
-
- int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name,
- grub_uint32_t block,
- grub_uint32_t size, int type,
- grub_uint32_t mtime)
- {
- grub_size_t len = grub_strlen (name);
- grub_uint8_t *name_u8;
- int ret;
- node = grub_malloc (sizeof (*node));
- if (!node)
- return 1;
- name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
- if (!name_u8)
- {
- grub_free (node);
- return 1;
- }
-
- node->data = data;
- node->size = size;
- node->block = block;
- node->mtime = mtime;
- node->cache = 0;
- node->cache_off = 0;
- node->next_extent = block;
- node->cache_size = 0;
- node->cache_allocated = 0;
-
- *grub_latin1_to_utf8 (name_u8, (const grub_uint8_t *) name, len) = '\0';
-
- ret = hook ((char *) name_u8, type | data->fshelp_flags, node);
- grub_free (name_u8);
- return ret;
- }
-
objc_data = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize);
if (!objc_data)
goto fail;
@@ -570,9 +566,10 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
else
block = grub_be_to_cpu32 (obj->file_dir.file.first_block);
- if (grub_sfs_create_node (filename, block,
+ if (grub_sfs_create_node (&node, data, filename, block,
grub_be_to_cpu32 (obj->file_dir.file.size),
- type, grub_be_to_cpu32 (obj->mtime)))
+ type, grub_be_to_cpu32 (obj->mtime),
+ hook, hook_data))
{
grub_free (objc_data);
return 1;
@@ -654,32 +651,38 @@ grub_sfs_read (grub_file_t file, char *buf, grub_size_t len)
}
+/* Context for grub_sfs_dir. */
+struct grub_sfs_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_sfs_dir. */
+static int
+grub_sfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_sfs_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2;
+ info.mtimeset = 1;
+ grub_free (node->cache);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
static grub_err_t
grub_sfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
+ struct grub_sfs_dir_ctx ctx = { hook, hook_data };
struct grub_sfs_data *data = 0;
struct grub_fshelp_node *fdiro = 0;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2;
- info.mtimeset = 1;
- grub_free (node->cache);
- grub_free (node);
- return hook (filename, &info);
- }
-
grub_dl_ref (my_mod);
data = grub_sfs_mount (device->disk);
@@ -691,7 +694,7 @@ grub_sfs_dir (grub_device_t device, const char *path,
if (grub_errno)
goto fail;
- grub_sfs_iterate_dir (fdiro, iterate);
+ grub_sfs_iterate_dir (fdiro, grub_sfs_dir_iter, &ctx);
fail:
if (data && fdiro != &data->diropen)
diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
index 44af0f8..cb3cc3a 100644
--- a/grub-core/fs/squash4.c
+++ b/grub-core/fs/squash4.c
@@ -478,10 +478,7 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
static int
grub_squash_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
grub_uint32_t off;
grub_uint32_t endoff;
@@ -514,7 +511,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
return 0;
grub_memcpy (node, dir,
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
- if (hook (".", GRUB_FSHELP_DIR, node))
+ if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
return 1;
if (dir->stsize != 1)
@@ -536,7 +533,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
if (err)
return 0;
- if (hook ("..", GRUB_FSHELP_DIR, node))
+ if (hook ("..", GRUB_FSHELP_DIR, node, hook_data))
return 1;
}
}
@@ -604,7 +601,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
node->stack[node->stsize].ino_offset = grub_le_to_cpu16 (di.ino_offset);
node->stsize++;
- r = hook (buf, filetype, node);
+ r = hook (buf, filetype, node, hook_data);
grub_free (buf);
if (r)
@@ -640,28 +637,34 @@ squash_unmount (struct grub_squash_data *data)
}
-static grub_err_t
-grub_squash_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+/* Context for grub_squash_dir. */
+struct grub_squash_dir_ctx
{
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- info.mtimeset = 1;
- info.mtime = grub_le_to_cpu32 (node->ino.mtime);
- grub_free (node);
- return hook (filename, &info);
- }
+/* Helper for grub_squash_dir. */
+static int
+grub_squash_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_squash_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+
+ grub_memset (&info, 0, sizeof (info));
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ info.mtimeset = 1;
+ info.mtime = grub_le_to_cpu32 (node->ino.mtime);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+static grub_err_t
+grub_squash_dir (grub_device_t device, const char *path,
+ grub_fs_dir_hook_t hook, void *hook_data)
+{
+ struct grub_squash_dir_ctx ctx = { hook, hook_data };
struct grub_squash_data *data = 0;
struct grub_fshelp_node *fdiro = 0;
struct grub_fshelp_node root;
@@ -678,7 +681,7 @@ grub_squash_dir (grub_device_t device, const char *path,
grub_fshelp_find_file (path, &root, &fdiro, grub_squash_iterate_dir,
grub_squash_read_symlink, GRUB_FSHELP_DIR);
if (!grub_errno)
- grub_squash_iterate_dir (fdiro, iterate);
+ grub_squash_iterate_dir (fdiro, grub_squash_dir_iter, &ctx);
squash_unmount (data);
diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
index 8e28d41..b7f3afb 100644
--- a/grub-core/fs/udf.c
+++ b/grub-core/fs/udf.c
@@ -843,10 +843,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
static int
grub_udf_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
grub_fshelp_node_t child;
struct grub_udf_file_ident dirent;
@@ -859,7 +856,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
/* The current directory is not stored. */
grub_memcpy (child, dir, get_fshelp_size (dir->data));
- if (hook (".", GRUB_FSHELP_DIR, child))
+ if (hook (".", GRUB_FSHELP_DIR, child, hook_data))
return 1;
while (offset < U64 (dir->block.fe.file_size))
@@ -887,7 +884,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
{
/* This is the parent directory. */
- if (hook ("..", GRUB_FSHELP_DIR, child))
+ if (hook ("..", GRUB_FSHELP_DIR, child, hook_data))
return 1;
}
else
@@ -911,7 +908,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
if (!filename)
grub_print_error ();
- if (filename && hook (filename, type, child))
+ if (filename && hook (filename, type, child, hook_data))
{
grub_free (filename);
return 1;
@@ -1012,58 +1009,64 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
return NULL;
}
+/* Context for grub_udf_dir. */
+struct grub_udf_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
+
+/* Helper for grub_udf_dir. */
+static int
+grub_udf_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_udf_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
+ const struct grub_udf_timestamp *tstamp = NULL;
+
+ grub_memset (&info, 0, sizeof (info));
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE)
+ tstamp = &node->block.fe.modification_time;
+ else if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE)
+ tstamp = &node->block.efe.modification_time;
+
+ if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000)
+ {
+ grub_int16_t tz;
+ struct grub_datetime datetime;
+
+ datetime.year = U16 (tstamp->year);
+ datetime.month = tstamp->month;
+ datetime.day = tstamp->day;
+ datetime.hour = tstamp->hour;
+ datetime.minute = tstamp->minute;
+ datetime.second = tstamp->second;
+
+ tz = U16 (tstamp->type_and_timezone) & 0xfff;
+ if (tz & 0x800)
+ tz |= 0xf000;
+ if (tz == -2047)
+ tz = 0;
+
+ info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime);
+
+ info.mtime -= 60 * tz;
+ }
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
static grub_err_t
grub_udf_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
+ struct grub_udf_dir_ctx ctx = { hook, hook_data };
struct grub_udf_data *data = 0;
struct grub_fshelp_node *rootnode = 0;
struct grub_fshelp_node *foundnode = 0;
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
-
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
- {
- struct grub_dirhook_info info;
- const struct grub_udf_timestamp *tstamp = NULL;
- grub_memset (&info, 0, sizeof (info));
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE)
- tstamp = &node->block.fe.modification_time;
- else if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE)
- tstamp = &node->block.efe.modification_time;
-
- if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000)
- {
- grub_int16_t tz;
- struct grub_datetime datetime;
-
- datetime.year = U16 (tstamp->year);
- datetime.month = tstamp->month;
- datetime.day = tstamp->day;
- datetime.hour = tstamp->hour;
- datetime.minute = tstamp->minute;
- datetime.second = tstamp->second;
-
- tz = U16 (tstamp->type_and_timezone) & 0xfff;
- if (tz & 0x800)
- tz |= 0xf000;
- if (tz == -2047)
- tz = 0;
-
- info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime);
-
- info.mtime -= 60 * tz;
- }
- grub_free (node);
- return hook (filename, &info);
- }
-
grub_dl_ref (my_mod);
data = grub_udf_mount (device->disk);
@@ -1083,7 +1086,7 @@ grub_udf_dir (grub_device_t device, const char *path,
GRUB_FSHELP_DIR))
goto fail;
- grub_udf_iterate_dir (foundnode, iterate);
+ grub_udf_iterate_dir (foundnode, grub_udf_dir_iter, &ctx);
if (foundnode != rootnode)
grub_free (foundnode);
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
index 74a4a40..089a5c6 100644
--- a/grub-core/fs/ufs.c
+++ b/grub-core/fs/ufs.c
@@ -625,8 +625,7 @@ grub_ufs_mount (grub_disk_t disk)
static grub_err_t
grub_ufs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
struct grub_ufs_data *data;
unsigned int pos = 0;
@@ -697,7 +696,7 @@ grub_ufs_dir (grub_device_t device, const char *path,
#endif
info.mtimeset = 1;
- if (hook (filename, &info))
+ if (hook (filename, &info, hook_data))
break;
}
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 1ed048f..49d2a89 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -443,47 +443,57 @@ grub_xfs_mode_to_filetype (grub_uint16_t mode)
}
-static int
-grub_xfs_iterate_dir (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node))
+/* Context for grub_xfs_iterate_dir. */
+struct grub_xfs_iterate_dir_ctx
{
- struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
- auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, const char *filename);
+ grub_fshelp_iterate_dir_hook_t hook;
+ void *hook_data;
+ struct grub_fshelp_node *diro;
+};
- int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, const char *filename)
- {
- struct grub_fshelp_node *fdiro;
- grub_err_t err;
-
- fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
- - sizeof (struct grub_xfs_inode)
- + (1 << diro->data->sblock.log2_inode));
- if (!fdiro)
- {
- grub_print_error ();
- return 0;
- }
+/* Helper for grub_xfs_iterate_dir. */
+static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
+ struct grub_xfs_iterate_dir_ctx *ctx)
+{
+ struct grub_fshelp_node *fdiro;
+ grub_err_t err;
- /* The inode should be read, otherwise the filetype can
- not be determined. */
- fdiro->ino = ino;
- fdiro->inode_read = 1;
- fdiro->data = diro->data;
- err = grub_xfs_read_inode (diro->data, ino, &fdiro->inode);
- if (err)
- {
- grub_print_error ();
- return 0;
- }
+ fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
+ - sizeof (struct grub_xfs_inode)
+ + (1 << ctx->diro->data->sblock.log2_inode));
+ if (!fdiro)
+ {
+ grub_print_error ();
+ return 0;
+ }
- return hook (filename,
- grub_xfs_mode_to_filetype (fdiro->inode.mode),
- fdiro);
+ /* The inode should be read, otherwise the filetype can
+ not be determined. */
+ fdiro->ino = ino;
+ fdiro->inode_read = 1;
+ fdiro->data = ctx->diro->data;
+ err = grub_xfs_read_inode (ctx->diro->data, ino, &fdiro->inode);
+ if (err)
+ {
+ grub_print_error ();
+ return 0;
}
+ return ctx->hook (filename, grub_xfs_mode_to_filetype (fdiro->inode.mode),
+ fdiro, ctx->hook_data);
+}
+
+static int
+grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
+{
+ struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
+ struct grub_xfs_iterate_dir_ctx ctx = {
+ .hook = hook,
+ .hook_data = hook_data,
+ .diro = diro
+ };
+
switch (diro->inode.format)
{
case XFS_INODE_FORMAT_INO:
@@ -508,10 +518,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
}
/* Synthesize the direntries for `.' and `..'. */
- if (call_hook (diro->ino, "."))
+ if (iterate_dir_call_hook (diro->ino, ".", &ctx))
return 1;
- if (call_hook (parent, ".."))
+ if (iterate_dir_call_hook (parent, "..", &ctx))
return 1;
for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
@@ -541,7 +551,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
grub_memcpy (name, de->name, de->len);
name[de->len] = '\0';
- if (call_hook (ino, name))
+ if (iterate_dir_call_hook (ino, name, &ctx))
return 1;
de = ((struct grub_xfs_dir_entry *)
@@ -619,7 +629,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
is not used by GRUB. So it can be overwritten. */
filename[direntry->len] = '\0';
- if (call_hook (direntry->inode, filename))
+ if (iterate_dir_call_hook (direntry->inode, filename, &ctx))
{
grub_free (dirblock);
return 1;
@@ -703,33 +713,39 @@ grub_xfs_mount (grub_disk_t disk)
}
-static grub_err_t
-grub_xfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+/* Context for grub_xfs_dir. */
+struct grub_xfs_dir_ctx
{
- struct grub_xfs_data *data = 0;
- struct grub_fshelp_node *fdiro = 0;
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+};
- auto int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node);
+/* Helper for grub_xfs_dir. */
+static int
+grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node, void *data)
+{
+ struct grub_xfs_dir_ctx *ctx = data;
+ struct grub_dirhook_info info;
- int NESTED_FUNC_ATTR iterate (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)
+ grub_memset (&info, 0, sizeof (info));
+ if (node->inode_read)
{
- struct grub_dirhook_info info;
- grub_memset (&info, 0, sizeof (info));
- if (node->inode_read)
- {
- info.mtimeset = 1;
- info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec);
- }
- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
- grub_free (node);
- return hook (filename, &info);
+ info.mtimeset = 1;
+ info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec);
}
+ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+ grub_free (node);
+ return ctx->hook (filename, &info, ctx->hook_data);
+}
+
+static grub_err_t
+grub_xfs_dir (grub_device_t device, const char *path,
+ grub_fs_dir_hook_t hook, void *hook_data)
+{
+ struct grub_xfs_dir_ctx ctx = { hook, hook_data };
+ struct grub_xfs_data *data = 0;
+ struct grub_fshelp_node *fdiro = 0;
grub_dl_ref (my_mod);
@@ -742,7 +758,7 @@ grub_xfs_dir (grub_device_t device, const char *path,
if (grub_errno)
goto fail;
- grub_xfs_iterate_dir (fdiro, iterate);
+ grub_xfs_iterate_dir (fdiro, grub_xfs_dir_iter, &ctx);
fail:
if (fdiro != &data->diropen)
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index ba0554a..822d65b 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -253,6 +253,14 @@ struct grub_zfs_data
grub_uint64_t guid;
};
+/* Context for grub_zfs_dir. */
+struct grub_zfs_dir_ctx
+{
+ grub_fs_dir_hook_t hook;
+ void *hook_data;
+ struct grub_zfs_data *data;
+};
+
grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher,
grub_uint64_t algo,
void *nonce,
@@ -988,43 +996,47 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data,
return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label");
}
-static grub_err_t
-scan_devices (struct grub_zfs_data *data)
+/* Helper for scan_devices. */
+static int
+scan_devices_iter (const char *name, void *hook_data)
{
- auto int hook (const char *name);
- int hook (const char *name)
- {
- grub_device_t dev;
- grub_err_t err;
- int inserted;
- dev = grub_device_open (name);
- if (!dev)
- return 0;
- if (!dev->disk)
- {
- grub_device_close (dev);
- return 0;
- }
- err = scan_disk (dev, data, 0, &inserted);
- if (err == GRUB_ERR_BAD_FS)
- {
- grub_device_close (dev);
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- if (err)
- {
- grub_device_close (dev);
- grub_print_error ();
- return 0;
- }
+ struct grub_zfs_data *data = hook_data;
+ grub_device_t dev;
+ grub_err_t err;
+ int inserted;
- if (!inserted)
- grub_device_close (dev);
-
+ dev = grub_device_open (name);
+ if (!dev)
return 0;
- }
- grub_device_iterate (hook);
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
+ return 0;
+ }
+ err = scan_disk (dev, data, 0, &inserted);
+ if (err == GRUB_ERR_BAD_FS)
+ {
+ grub_device_close (dev);
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (err)
+ {
+ grub_device_close (dev);
+ grub_print_error ();
+ return 0;
+ }
+
+ if (!inserted)
+ grub_device_close (dev);
+
+ return 0;
+}
+
+static grub_err_t
+scan_devices (struct grub_zfs_data *data)
+{
+ grub_device_iterate (scan_devices_iter, data);
return GRUB_ERR_NONE;
}
@@ -1786,8 +1798,9 @@ mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
static int
mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize,
- int NESTED_FUNC_ATTR (*hook) (const char *name,
- grub_uint64_t val))
+ int (*hook) (const char *name, grub_uint64_t val,
+ struct grub_zfs_dir_ctx *ctx),
+ struct grub_zfs_dir_ctx *ctx)
{
int i, chunks;
mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;
@@ -1799,7 +1812,7 @@ mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize,
mzap_ent[i].mze_name, (long long)mzap_ent[i].mze_value,
(int)mzap_ent[i].mze_cd);
if (hook (mzap_ent[i].mze_name,
- grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian)))
+ grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian), ctx))
return 1;
}
@@ -2050,12 +2063,11 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap,
static int
fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
grub_size_t name_elem_length,
- int NESTED_FUNC_ATTR (*hook) (const void *name,
- grub_size_t name_length,
- const void *val_in,
- grub_size_t nelem,
- grub_size_t elemsize),
- struct grub_zfs_data *data)
+ int (*hook) (const void *name, grub_size_t name_length,
+ const void *val_in,
+ grub_size_t nelem, grub_size_t elemsize,
+ void *data),
+ void *hook_data, struct grub_zfs_data *data)
{
zap_leaf_phys_t *l;
void *l_in;
@@ -2154,7 +2166,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
}
if (hook (buf, le->le_name_length,
- val, le->le_value_length, le->le_int_size))
+ val, le->le_value_length, le->le_int_size, hook_data))
{
grub_free (l);
return 1;
@@ -2217,11 +2229,35 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type");
}
+/* Context for zap_iterate_u64. */
+struct zap_iterate_u64_ctx
+{
+ int (*hook) (const char *, grub_uint64_t, struct grub_zfs_dir_ctx *);
+ struct grub_zfs_dir_ctx *dir_ctx;
+};
+
+/* Helper for zap_iterate_u64. */
+static int
+zap_iterate_u64_transform (const void *name,
+ grub_size_t namelen __attribute__ ((unused)),
+ const void *val_in,
+ grub_size_t nelem,
+ grub_size_t elemsize,
+ void *data)
+{
+ struct zap_iterate_u64_ctx *ctx = data;
+
+ if (elemsize != sizeof (grub_uint64_t) || nelem != 1)
+ return 0;
+ return ctx->hook (name, grub_be_to_cpu64 (*(const grub_uint64_t *) val_in),
+ ctx->dir_ctx);
+}
+
static int
zap_iterate_u64 (dnode_end_t * zap_dnode,
- int NESTED_FUNC_ATTR (*hook) (const char *name,
- grub_uint64_t val),
- struct grub_zfs_data *data)
+ int (*hook) (const char *name, grub_uint64_t val,
+ struct grub_zfs_dir_ctx *ctx),
+ struct grub_zfs_data *data, struct grub_zfs_dir_ctx *ctx)
{
grub_uint64_t block_type;
int size;
@@ -2230,23 +2266,6 @@ zap_iterate_u64 (dnode_end_t * zap_dnode,
int ret;
grub_zfs_endian_t endian;
- auto int NESTED_FUNC_ATTR transform (const void *name,
- grub_size_t namelen,
- const void *val_in,
- grub_size_t nelem,
- grub_size_t elemsize);
-
- int NESTED_FUNC_ATTR transform (const void *name,
- grub_size_t namelen __attribute__ ((unused)),
- const void *val_in,
- grub_size_t nelem,
- grub_size_t elemsize)
- {
- if (elemsize != sizeof (grub_uint64_t) || nelem != 1)
- return 0;
- return hook (name, grub_be_to_cpu64 (*(const grub_uint64_t *) val_in));
- }
-
/* Read in the first block of the zap object data. */
size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT;
err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
@@ -2259,15 +2278,21 @@ zap_iterate_u64 (dnode_end_t * zap_dnode,
if (block_type == ZBT_MICRO)
{
grub_dprintf ("zfs", "micro zap\n");
- ret = mzap_iterate (zapbuf, endian, size, hook);
+ ret = mzap_iterate (zapbuf, endian, size, hook, ctx);
grub_free (zapbuf);
return ret;
}
else if (block_type == ZBT_HEADER)
{
+ struct zap_iterate_u64_ctx transform_ctx = {
+ .hook = hook,
+ .dir_ctx = ctx
+ };
+
grub_dprintf ("zfs", "fat zap\n");
/* this is a fat zap */
- ret = fzap_iterate (zap_dnode, zapbuf, 1, transform, data);
+ ret = fzap_iterate (zap_dnode, zapbuf, 1,
+ zap_iterate_u64_transform, &transform_ctx, data);
grub_free (zapbuf);
return ret;
}
@@ -2278,12 +2303,11 @@ zap_iterate_u64 (dnode_end_t * zap_dnode,
static int
zap_iterate (dnode_end_t * zap_dnode,
grub_size_t nameelemlen,
- int NESTED_FUNC_ATTR (*hook) (const void *name,
- grub_size_t namelen,
- const void *val_in,
- grub_size_t nelem,
- grub_size_t elemsize),
- struct grub_zfs_data *data)
+ int (*hook) (const void *name, grub_size_t namelen,
+ const void *val_in,
+ grub_size_t nelem, grub_size_t elemsize,
+ void *data),
+ void *hook_data, struct grub_zfs_data *data)
{
grub_uint64_t block_type;
void *zapbuf;
@@ -2308,7 +2332,8 @@ zap_iterate (dnode_end_t * zap_dnode,
{
grub_dprintf ("zfs", "fat zap\n");
/* this is a fat zap */
- ret = fzap_iterate (zap_dnode, zapbuf, nameelemlen, hook, data);
+ ret = fzap_iterate (zap_dnode, zapbuf, nameelemlen, hook, hook_data,
+ data);
grub_free (zapbuf);
return ret;
}
@@ -2822,6 +2847,61 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
return GRUB_ERR_NONE;
}
+/* Context for dnode_get_fullpath. */
+struct dnode_get_fullpath_ctx
+{
+ struct subvolume *subvol;
+ grub_uint64_t salt;
+ int keyn;
+};
+
+/* Helper for dnode_get_fullpath. */
+static int
+count_zap_keys (const void *name __attribute__ ((unused)),
+ grub_size_t namelen __attribute__ ((unused)),
+ const void *val_in __attribute__ ((unused)),
+ grub_size_t nelem __attribute__ ((unused)),
+ grub_size_t elemsize __attribute__ ((unused)),
+ void *data)
+{
+ struct dnode_get_fullpath_ctx *ctx = data;
+
+ ctx->subvol->nkeys++;
+ return 0;
+}
+
+/* Helper for dnode_get_fullpath. */
+static int
+load_zap_key (const void *name, grub_size_t namelen, const void *val_in,
+ grub_size_t nelem, grub_size_t elemsize, void *data)
+{
+ struct dnode_get_fullpath_ctx *ctx = data;
+
+ if (namelen != 1)
+ {
+ grub_dprintf ("zfs", "Unexpected key index size %" PRIuGRUB_SIZE "\n",
+ namelen);
+ return 0;
+ }
+
+ if (elemsize != 1)
+ {
+ grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n",
+ elemsize);
+ return 0;
+ }
+
+ ctx->subvol->keyring[ctx->keyn].txg =
+ grub_be_to_cpu64 (*(grub_uint64_t *) name);
+ ctx->subvol->keyring[ctx->keyn].algo =
+ grub_le_to_cpu64 (*(grub_uint64_t *) val_in);
+ ctx->subvol->keyring[ctx->keyn].cipher =
+ grub_zfs_load_key (val_in, nelem, ctx->salt,
+ ctx->subvol->keyring[ctx->keyn].algo);
+ ctx->keyn++;
+ return 0;
+}
+
static grub_err_t
dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
dnode_end_t * dn, int *isfs,
@@ -2831,57 +2911,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
const char *ptr_at, *filename;
grub_uint64_t headobj;
grub_uint64_t keychainobj;
- grub_uint64_t salt;
grub_err_t err;
- int keyn = 0;
-
- auto int NESTED_FUNC_ATTR count_zap_keys (const void *name,
- grub_size_t namelen,
- const void *val_in,
- grub_size_t nelem,
- grub_size_t elemsize);
- int NESTED_FUNC_ATTR count_zap_keys (const void *name __attribute__ ((unused)),
- grub_size_t namelen __attribute__ ((unused)),
- const void *val_in __attribute__ ((unused)),
- grub_size_t nelem __attribute__ ((unused)),
- grub_size_t elemsize __attribute__ ((unused)))
- {
- subvol->nkeys++;
- return 0;
- }
-
- auto int NESTED_FUNC_ATTR load_zap_key (const void *name,
- grub_size_t namelen,
- const void *val_in,
- grub_size_t nelem,
- grub_size_t elemsize);
- int NESTED_FUNC_ATTR load_zap_key (const void *name,
- grub_size_t namelen,
- const void *val_in,
- grub_size_t nelem,
- grub_size_t elemsize)
- {
- if (namelen != 1)
- {
- grub_dprintf ("zfs", "Unexpected key index size %" PRIuGRUB_SIZE "\n",
- namelen);
- return 0;
- }
-
- if (elemsize != 1)
- {
- grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n",
- elemsize);
- return 0;
- }
-
- subvol->keyring[keyn].txg = grub_be_to_cpu64 (*(grub_uint64_t *) name);
- subvol->keyring[keyn].algo = grub_le_to_cpu64 (*(grub_uint64_t *) val_in);
- subvol->keyring[keyn].cipher = grub_zfs_load_key (val_in, nelem, salt,
- subvol->keyring[keyn].algo);
- keyn++;
- return 0;
- }
ptr_at = grub_strchr (fullpath, '@');
if (! ptr_at)
@@ -2949,6 +2979,10 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian);
if (grub_zfs_load_key && keychainobj)
{
+ struct dnode_get_fullpath_ctx ctx = {
+ .subvol = subvol,
+ .keyn = 0
+ };
dnode_end_t keychain_dn, props_dn;
grub_uint64_t propsobj;
propsobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_props_zapobj, dn->endian);
@@ -2962,12 +2996,12 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
return err;
}
- err = zap_lookup (&props_dn, "salt", &salt, data, 0);
+ err = zap_lookup (&props_dn, "salt", &ctx.salt, data, 0);
if (err == GRUB_ERR_FILE_NOT_FOUND)
{
err = 0;
grub_errno = 0;
- salt = 0;
+ ctx.salt = 0;
}
if (err)
{
@@ -2984,7 +3018,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
return err;
}
subvol->nkeys = 0;
- zap_iterate (&keychain_dn, 8, count_zap_keys, data);
+ zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data);
subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0]));
if (!subvol->keyring)
{
@@ -2992,7 +3026,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
grub_free (snapname);
return err;
}
- zap_iterate (&keychain_dn, 8, load_zap_key, data);
+ zap_iterate (&keychain_dn, 8, load_zap_key, &ctx, data);
}
if (snapname)
@@ -3744,108 +3778,122 @@ fill_fs_info (struct grub_dirhook_info *info,
return;
}
-static grub_err_t
-grub_zfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *, const struct grub_dirhook_info *))
+/* Helper for grub_zfs_dir. */
+static int
+iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx)
{
- struct grub_zfs_data *data;
grub_err_t err;
- int isfs;
- auto int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val);
- auto int NESTED_FUNC_ATTR iterate_zap_fs (const char *name,
- grub_uint64_t val);
- auto int NESTED_FUNC_ATTR iterate_zap_snap (const char *name,
- grub_uint64_t val);
+ struct grub_dirhook_info info;
- int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val)
- {
- struct grub_dirhook_info info;
- dnode_end_t dn;
- grub_memset (&info, 0, sizeof (info));
+ dnode_end_t dn;
+ grub_memset (&info, 0, sizeof (info));
- dnode_get (&(data->subvol.mdn), val, 0, &dn, data);
+ dnode_get (&(ctx->data->subvol.mdn), val, 0, &dn, ctx->data);
- if (dn.dn.dn_bonustype == DMU_OT_SA)
- {
- void *sahdrp;
- int hdrsize;
+ if (dn.dn.dn_bonustype == DMU_OT_SA)
+ {
+ void *sahdrp;
+ int hdrsize;
- if (dn.dn.dn_bonuslen != 0)
- {
- sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn);
- }
- else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
- {
- blkptr_t *bp = &dn.dn.dn_spill;
+ if (dn.dn.dn_bonuslen != 0)
+ {
+ sahdrp = (sa_hdr_phys_t *) DN_BONUS (&ctx->data->dnode.dn);
+ }
+ else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
+ {
+ blkptr_t *bp = &dn.dn.dn_spill;
- err = zio_read (bp, dn.endian, &sahdrp, NULL, data);
- if (err)
- {
- grub_print_error ();
- return 0;
- }
- }
- else
- {
- grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
- grub_print_error ();
- return 0;
- }
+ err = zio_read (bp, dn.endian, &sahdrp, NULL, ctx->data);
+ if (err)
+ {
+ grub_print_error ();
+ return 0;
+ }
+ }
+ else
+ {
+ grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
+ grub_print_error ();
+ return 0;
+ }
- hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
- info.mtimeset = 1;
- info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
- info.case_insensitive = data->subvol.case_insensitive;
- }
-
- if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
- {
- info.mtimeset = 1;
- info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0],
- dn.endian);
- }
- info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS);
- grub_dprintf ("zfs", "type=%d, name=%s\n",
- (int)dn.dn.dn_type, (char *)name);
- return hook (name, &info);
- }
+ hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
+ info.mtimeset = 1;
+ info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
+ info.case_insensitive = ctx->data->subvol.case_insensitive;
+ }
+
+ if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
+ {
+ info.mtimeset = 1;
+ info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0],
+ dn.endian);
+ }
+ info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS);
+ grub_dprintf ("zfs", "type=%d, name=%s\n",
+ (int)dn.dn.dn_type, (char *)name);
+ return ctx->hook (name, &info, ctx->hook_data);
+}
- int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val)
- {
- struct grub_dirhook_info info;
- dnode_end_t mdn;
- err = dnode_get (&(data->mos), val, 0, &mdn, data);
- if (err)
- return 0;
- if (mdn.dn.dn_type != DMU_OT_DSL_DIR)
- return 0;
+/* Helper for grub_zfs_dir. */
+static int
+iterate_zap_fs (const char *name, grub_uint64_t val,
+ struct grub_zfs_dir_ctx *ctx)
+{
+ grub_err_t err;
+ struct grub_dirhook_info info;
- fill_fs_info (&info, mdn, data);
- return hook (name, &info);
- }
- int NESTED_FUNC_ATTR iterate_zap_snap (const char *name, grub_uint64_t val)
- {
- struct grub_dirhook_info info;
- char *name2;
- int ret;
- dnode_end_t mdn;
+ dnode_end_t mdn;
+ err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data);
+ if (err)
+ return 0;
+ if (mdn.dn.dn_type != DMU_OT_DSL_DIR)
+ return 0;
- err = dnode_get (&(data->mos), val, 0, &mdn, data);
- if (err)
- return 0;
+ fill_fs_info (&info, mdn, ctx->data);
+ return ctx->hook (name, &info, ctx->hook_data);
+}
- if (mdn.dn.dn_type != DMU_OT_DSL_DATASET)
- return 0;
+/* Helper for grub_zfs_dir. */
+static int
+iterate_zap_snap (const char *name, grub_uint64_t val,
+ struct grub_zfs_dir_ctx *ctx)
+{
+ grub_err_t err;
+ struct grub_dirhook_info info;
+ char *name2;
+ int ret;
- fill_fs_info (&info, mdn, data);
+ dnode_end_t mdn;
- name2 = grub_malloc (grub_strlen (name) + 2);
- name2[0] = '@';
- grub_memcpy (name2 + 1, name, grub_strlen (name) + 1);
- ret = hook (name2, &info);
- grub_free (name2);
- return ret;
- }
+ err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data);
+ if (err)
+ return 0;
+
+ if (mdn.dn.dn_type != DMU_OT_DSL_DATASET)
+ return 0;
+
+ fill_fs_info (&info, mdn, ctx->data);
+
+ name2 = grub_malloc (grub_strlen (name) + 2);
+ name2[0] = '@';
+ grub_memcpy (name2 + 1, name, grub_strlen (name) + 1);
+ ret = ctx->hook (name2, &info, ctx->hook_data);
+ grub_free (name2);
+ return ret;
+}
+
+static grub_err_t
+grub_zfs_dir (grub_device_t device, const char *path,
+ grub_fs_dir_hook_t hook, void *hook_data)
+{
+ struct grub_zfs_dir_ctx ctx = {
+ .hook = hook,
+ .hook_data = hook_data
+ };
+ struct grub_zfs_data *data;
+ grub_err_t err;
+ int isfs;
data = zfs_mount (device);
if (! data)
@@ -3856,6 +3904,8 @@ grub_zfs_dir (grub_device_t device, const char *path,
zfs_unmount (data);
return err;
}
+ ctx.data = data;
+
if (isfs)
{
grub_uint64_t childobj, headobj;
@@ -3864,7 +3914,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info;
fill_fs_info (&info, data->dnode, data);
- hook ("@", &info);
+ hook ("@", &info, hook_data);
childobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_child_dir_zapobj, data->dnode.endian);
headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_head_dataset_obj, data->dnode.endian);
@@ -3876,7 +3926,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
return err;
}
- zap_iterate_u64 (&dn, iterate_zap_fs, data);
+ zap_iterate_u64 (&dn, iterate_zap_fs, data, &ctx);
err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &dn, data);
if (err)
@@ -3895,7 +3945,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
return err;
}
- zap_iterate_u64 (&dn, iterate_zap_snap, data);
+ zap_iterate_u64 (&dn, iterate_zap_snap, data, &ctx);
}
else
{
@@ -3904,7 +3954,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
zfs_unmount (data);
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
}
- zap_iterate_u64 (&(data->dnode), iterate_zap, data);
+ zap_iterate_u64 (&(data->dnode), iterate_zap, data, &ctx);
}
zfs_unmount (data);
return grub_errno;
diff --git a/grub-core/gfxmenu/font.c b/grub-core/gfxmenu/font.c
index 3c15e19..81a689d 100644
--- a/grub-core/gfxmenu/font.c
+++ b/grub-core/gfxmenu/font.c
@@ -52,7 +52,7 @@ grub_font_draw_string (const char *str, grub_font_t font,
return grub_errno;
visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual,
- 0, 0, 0);
+ 0, 0, 0, 0, 0, 0);
grub_free (logical);
if (visual_len < 0)
return grub_errno;
diff --git a/grub-core/gnulib/stdio.in.h b/grub-core/gnulib/stdio.in.h
index 80b9dbf..a8b00c6 100644
--- a/grub-core/gnulib/stdio.in.h
+++ b/grub-core/gnulib/stdio.in.h
@@ -138,10 +138,12 @@ _GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - "
#endif
/* It is very rare that the developer ever has full control of stdin,
- so any use of gets warrants an unconditional warning. Assume it is
- always declared, since it is required by C89. */
+ so any use of gets warrants an unconditional warning; besides, C11
+ removed it. */
#undef gets
+#if HAVE_RAW_DECL_GETS
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
+#endif
#if @GNULIB_FOPEN@
# if @REPLACE_FOPEN@
diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c
index 2a315e2..2243827 100644
--- a/grub-core/io/bufio.c
+++ b/grub-core/io/bufio.c
@@ -48,7 +48,7 @@ grub_bufio_open (grub_file_t io, int size)
grub_file_t file;
grub_bufio_t bufio = 0;
- file = (grub_file_t) grub_malloc (sizeof (*file));
+ file = (grub_file_t) grub_zalloc (sizeof (*file));
if (! file)
return 0;
@@ -61,7 +61,7 @@ grub_bufio_open (grub_file_t io, int size)
size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE :
io->size);
- bufio = grub_malloc (sizeof (struct grub_bufio) + size);
+ bufio = grub_zalloc (sizeof (struct grub_bufio) + size);
if (! bufio)
{
grub_free (file);
@@ -70,14 +70,10 @@ grub_bufio_open (grub_file_t io, int size)
bufio->file = io;
bufio->block_size = size;
- bufio->buffer_len = 0;
- bufio->buffer_at = 0;
file->device = io->device;
- file->offset = 0;
file->size = io->size;
file->data = bufio;
- file->read_hook = 0;
file->fs = &grub_bufio_fs;
file->not_easily_seekable = io->not_easily_seekable;
diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
index 83c0b64..ef5872a 100644
--- a/grub-core/io/gzio.c
+++ b/grub-core/io/gzio.c
@@ -1125,12 +1125,12 @@ initialize_tables (grub_gzio_t gzio)
even if IO does not contain data compressed by gzip, return a valid file
object. Note that this function won't close IO, even if an error occurs. */
static grub_file_t
-grub_gzio_open (grub_file_t io)
+grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused)))
{
grub_file_t file;
grub_gzio_t gzio = 0;
- file = (grub_file_t) grub_malloc (sizeof (*file));
+ file = (grub_file_t) grub_zalloc (sizeof (*file));
if (! file)
return 0;
@@ -1144,9 +1144,7 @@ grub_gzio_open (grub_file_t io)
gzio->file = io;
file->device = io->device;
- file->offset = 0;
file->data = gzio;
- file->read_hook = 0;
file->fs = &grub_gzio_fs;
file->not_easily_seekable = 1;
diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c
index 77291d0..63bfbad 100644
--- a/grub-core/io/lzopio.c
+++ b/grub-core/io/lzopio.c
@@ -409,7 +409,8 @@ CORRUPTED:
}
static grub_file_t
-grub_lzopio_open (grub_file_t io)
+grub_lzopio_open (grub_file_t io,
+ const char *name __attribute__ ((unused)))
{
grub_file_t file;
grub_lzopio_t lzopio;
@@ -428,9 +429,7 @@ grub_lzopio_open (grub_file_t io)
lzopio->file = io;
file->device = io->device;
- file->offset = 0;
file->data = lzopio;
- file->read_hook = 0;
file->fs = &grub_lzopio_fs;
file->size = GRUB_FILE_SIZE_UNKNOWN;
file->not_easily_seekable = 1;
diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c
index ae30e6f..bcce242 100644
--- a/grub-core/io/xzio.c
+++ b/grub-core/io/xzio.c
@@ -169,7 +169,8 @@ ERROR:
}
static grub_file_t
-grub_xzio_open (grub_file_t io)
+grub_xzio_open (grub_file_t io,
+ const char *name __attribute__ ((unused)))
{
grub_file_t file;
grub_xzio_t xzio;
@@ -186,12 +187,9 @@ grub_xzio_open (grub_file_t io)
}
xzio->file = io;
- xzio->saved_offset = 0;
file->device = io->device;
- file->offset = 0;
file->data = xzio;
- file->read_hook = 0;
file->fs = &grub_xzio_fs;
file->size = GRUB_FILE_SIZE_UNKNOWN;
file->not_easily_seekable = 1;
@@ -210,10 +208,7 @@ grub_xzio_open (grub_file_t io)
}
xzio->buf.in = xzio->inbuf;
- xzio->buf.in_pos = 0;
- xzio->buf.in_size = 0;
xzio->buf.out = xzio->outbuf;
- xzio->buf.out_pos = 0;
xzio->buf.out_size = XZBUFSIZ;
/* FIXME: don't test footer on not easily seekable files. */
diff --git a/grub-core/kern/arm/uboot/startup.S b/grub-core/kern/arm/uboot/startup.S
index 51ea91e..96f732f 100644
--- a/grub-core/kern/arm/uboot/startup.S
+++ b/grub-core/kern/arm/uboot/startup.S
@@ -104,7 +104,7 @@ FUNCTION(codestart)
ldr r12, =EXT_C(uboot_boot_data)
str r5, [r12]
- b grub_main
+ b EXT_C(grub_main)
/*
* uboot_syscall():
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
index eec575c..0dc4d00 100644
--- a/grub-core/kern/corecmd.c
+++ b/grub-core/kern/corecmd.c
@@ -28,6 +28,14 @@
#include <grub/command.h>
#include <grub/i18n.h>
+/* Helper for grub_core_cmd_set. */
+static int
+print_env (struct grub_env_var *env)
+{
+ grub_printf ("%s=%s\n", env->name, env->value);
+ return 0;
+}
+
/* set ENVVAR=VALUE */
static grub_err_t
grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)),
@@ -36,14 +44,6 @@ grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)),
char *var;
char *val;
- auto int print_env (struct grub_env_var *env);
-
- int print_env (struct grub_env_var *env)
- {
- grub_printf ("%s=%s\n", env->name, env->value);
- return 0;
- }
-
if (argc < 1)
{
grub_env_iterate (print_env);
@@ -96,7 +96,7 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
}
static int
-grub_mini_print_devices (const char *name)
+grub_mini_print_devices (const char *name, void *data __attribute__ ((unused)))
{
grub_printf ("(%s) ", name);
@@ -105,7 +105,8 @@ grub_mini_print_devices (const char *name)
static int
grub_mini_print_files (const char *filename,
- const struct grub_dirhook_info *info)
+ const struct grub_dirhook_info *info,
+ void *data __attribute__ ((unused)))
{
grub_printf ("%s%s ", filename, info->dir ? "/" : "");
@@ -119,7 +120,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
{
if (argc < 1)
{
- grub_device_iterate (grub_mini_print_devices);
+ grub_device_iterate (grub_mini_print_devices, NULL);
grub_xputs ("\n");
grub_refresh ();
}
@@ -160,7 +161,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
}
else if (fs)
{
- (fs->dir) (dev, path, grub_mini_print_files);
+ (fs->dir) (dev, path, grub_mini_print_files, NULL);
grub_xputs ("\n");
grub_refresh ();
}
diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c
index 1261564..73b8ecc 100644
--- a/grub-core/kern/device.c
+++ b/grub-core/kern/device.c
@@ -85,94 +85,107 @@ grub_device_close (grub_device_t device)
return grub_errno;
}
-int
-grub_device_iterate (int (*hook) (const char *name))
+struct part_ent
{
- auto int iterate_disk (const char *disk_name);
- auto int iterate_partition (grub_disk_t disk,
- const grub_partition_t partition);
+ struct part_ent *next;
+ char *name;
+};
- struct part_ent
- {
- struct part_ent *next;
- char *name;
- } *ents;
+/* Context for grub_device_iterate. */
+struct grub_device_iterate_ctx
+{
+ grub_device_iterate_hook_t hook;
+ void *hook_data;
+ struct part_ent *ents;
+};
+
+/* Helper for grub_device_iterate. */
+static int
+iterate_partition (grub_disk_t disk, const grub_partition_t partition,
+ void *data)
+{
+ struct grub_device_iterate_ctx *ctx = data;
+ struct part_ent *p;
+ char *part_name;
- int iterate_disk (const char *disk_name)
+ p = grub_malloc (sizeof (*p));
+ if (!p)
{
- grub_device_t dev;
-
- if (hook (disk_name))
- return 1;
-
- dev = grub_device_open (disk_name);
- if (! dev)
- {
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
-
- if (dev->disk)
- {
- struct part_ent *p;
- int ret = 0;
+ return 1;
+ }
- ents = NULL;
- (void) grub_partition_iterate (dev->disk, iterate_partition);
- grub_device_close (dev);
+ part_name = grub_partition_get_name (partition);
+ if (!part_name)
+ {
+ grub_free (p);
+ return 1;
+ }
+ p->name = grub_xasprintf ("%s,%s", disk->name, part_name);
+ grub_free (part_name);
+ if (!p->name)
+ {
+ grub_free (p);
+ return 1;
+ }
- grub_errno = GRUB_ERR_NONE;
+ p->next = ctx->ents;
+ ctx->ents = p;
- p = ents;
- while (p != NULL)
- {
- struct part_ent *next = p->next;
+ return 0;
+}
- if (!ret)
- ret = hook (p->name);
- grub_free (p->name);
- grub_free (p);
- p = next;
- }
+/* Helper for grub_device_iterate. */
+static int
+iterate_disk (const char *disk_name, void *data)
+{
+ struct grub_device_iterate_ctx *ctx = data;
+ grub_device_t dev;
- return ret;
- }
+ if (ctx->hook (disk_name, ctx->hook_data))
+ return 1;
- grub_device_close (dev);
+ dev = grub_device_open (disk_name);
+ if (! dev)
+ {
+ grub_errno = GRUB_ERR_NONE;
return 0;
}
- int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
+ if (dev->disk)
{
struct part_ent *p;
- char *part_name;
+ int ret = 0;
- p = grub_malloc (sizeof (*p));
- if (!p)
- {
- return 1;
- }
+ ctx->ents = NULL;
+ (void) grub_partition_iterate (dev->disk, iterate_partition, ctx);
+ grub_device_close (dev);
- part_name = grub_partition_get_name (partition);
- if (!part_name)
- {
- grub_free (p);
- return 1;
- }
- p->name = grub_xasprintf ("%s,%s", disk->name, part_name);
- grub_free (part_name);
- if (!p->name)
+ grub_errno = GRUB_ERR_NONE;
+
+ p = ctx->ents;
+ while (p != NULL)
{
+ struct part_ent *next = p->next;
+
+ if (!ret)
+ ret = ctx->hook (p->name, ctx->hook_data);
+ grub_free (p->name);
grub_free (p);
- return 1;
+ p = next;
}
- p->next = ents;
- ents = p;
-
- return 0;
+ return ret;
}
+ grub_device_close (dev);
+ return 0;
+}
+
+int
+grub_device_iterate (grub_device_iterate_hook_t hook, void *hook_data)
+{
+ struct grub_device_iterate_ctx ctx = { hook, hook_data, NULL };
+
/* Only disk devices are supported at the moment. */
- return grub_disk_dev_iterate (iterate_disk);
+ return grub_disk_dev_iterate (iterate_disk, &ctx);
}
diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c
index 1f55f90..94318af 100644
--- a/grub-core/kern/disk.c
+++ b/grub-core/kern/disk.c
@@ -658,7 +658,8 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
grub_disk_cache_invalidate (disk->dev->id, disk->id, sector);
- if ((disk->dev->write) (disk, sector, 1, tmp_buf) != GRUB_ERR_NONE)
+ if ((disk->dev->write) (disk, transform_sector (disk, sector),
+ 1, tmp_buf) != GRUB_ERR_NONE)
goto finish;
sector += (1 << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS));
@@ -674,11 +675,15 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
len = size & ~((1 << disk->log_sector_size) - 1);
n = size >> disk->log_sector_size;
- if ((disk->dev->write) (disk, sector, n, buf) != GRUB_ERR_NONE)
+ if ((disk->dev->write) (disk, transform_sector (disk, sector),
+ n, buf) != GRUB_ERR_NONE)
goto finish;
while (n--)
- grub_disk_cache_invalidate (disk->dev->id, disk->id, sector++);
+ {
+ grub_disk_cache_invalidate (disk->dev->id, disk->id, sector);
+ sector += (1 << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS));
+ }
buf = (const char *) buf + len;
size -= len;
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index a2edc84..351317b 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -109,37 +109,36 @@ grub_efi_free_pages (grub_efi_physical_address_t address,
#if defined (__i386__) || defined (__x86_64__)
-static void
-stop_broadcom (void)
+/* Helper for stop_broadcom. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
{
- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
- grub_pci_id_t pciid);
-
- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
- grub_pci_id_t pciid)
- {
- grub_pci_address_t addr;
- grub_uint8_t cap;
- grub_uint16_t pm_state;
+ grub_pci_address_t addr;
+ grub_uint8_t cap;
+ grub_uint16_t pm_state;
- if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM)
- return 0;
+ if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM)
+ return 0;
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
- if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK)
- return 0;
- cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT);
- if (!cap)
- return 0;
- addr = grub_pci_make_address (dev, cap + 4);
- pm_state = grub_pci_read_word (addr);
- pm_state = pm_state | 0x03;
- grub_pci_write_word (addr, pm_state);
- grub_pci_read_word (addr);
- return 0;
- }
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK)
+ return 0;
+ cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT);
+ if (!cap)
+ return 0;
+ addr = grub_pci_make_address (dev, cap + 4);
+ pm_state = grub_pci_read_word (addr);
+ pm_state = pm_state | 0x03;
+ grub_pci_write_word (addr, pm_state);
+ grub_pci_read_word (addr);
+ return 0;
+}
- grub_pci_iterate (find_card);
+static void
+stop_broadcom (void)
+{
+ grub_pci_iterate (find_card, NULL);
}
#endif
diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c
index 682cfbd..f52ca21 100644
--- a/grub-core/kern/elf.c
+++ b/grub-core/kern/elf.c
@@ -149,8 +149,7 @@ grub_elf32_load_phdrs (grub_elf_t elf, const char *filename)
grub_err_t
grub_elf32_phdr_iterate (grub_elf_t elf,
const char *filename,
- int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *),
- void *hook_arg)
+ grub_elf32_phdr_iterate_hook_t hook, void *hook_arg)
{
Elf32_Phdr *phdrs;
unsigned int i;
@@ -177,48 +176,58 @@ grub_elf32_phdr_iterate (grub_elf_t elf,
return grub_errno;
}
+struct grub_elf32_size_ctx
+{
+ Elf32_Addr segments_start, segments_end;
+ int nr_phdrs;
+ grub_uint32_t curr_align;
+};
+
+/* Run through the program headers to calculate the total memory size we
+ * should claim. */
+static int
+grub_elf32_calcsize (grub_elf_t _elf __attribute__ ((unused)),
+ Elf32_Phdr *phdr, void *data)
+{
+ struct grub_elf32_size_ctx *ctx = data;
+
+ /* Only consider loadable segments. */
+ if (phdr->p_type != PT_LOAD)
+ return 0;
+ ctx->nr_phdrs++;
+ if (phdr->p_paddr < ctx->segments_start)
+ ctx->segments_start = phdr->p_paddr;
+ if (phdr->p_paddr + phdr->p_memsz > ctx->segments_end)
+ ctx->segments_end = phdr->p_paddr + phdr->p_memsz;
+ if (ctx->curr_align < phdr->p_align)
+ ctx->curr_align = phdr->p_align;
+ return 0;
+}
+
/* Calculate the amount of memory spanned by the segments. */
grub_size_t
grub_elf32_size (grub_elf_t elf, const char *filename,
Elf32_Addr *base, grub_uint32_t *max_align)
{
- Elf32_Addr segments_start = (Elf32_Addr) -1;
- Elf32_Addr segments_end = 0;
- int nr_phdrs = 0;
- grub_uint32_t curr_align = 1;
-
- /* Run through the program headers to calculate the total memory size we
- * should claim. */
- auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg);
- int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
- Elf32_Phdr *phdr,
- void *_arg __attribute__ ((unused)))
- {
- /* Only consider loadable segments. */
- if (phdr->p_type != PT_LOAD)
- return 0;
- nr_phdrs++;
- if (phdr->p_paddr < segments_start)
- segments_start = phdr->p_paddr;
- if (phdr->p_paddr + phdr->p_memsz > segments_end)
- segments_end = phdr->p_paddr + phdr->p_memsz;
- if (curr_align < phdr->p_align)
- curr_align = phdr->p_align;
- return 0;
- }
+ struct grub_elf32_size_ctx ctx = {
+ .segments_start = (Elf32_Addr) -1,
+ .segments_end = 0,
+ .nr_phdrs = 0,
+ .curr_align = 1
+ };
- grub_elf32_phdr_iterate (elf, filename, calcsize, 0);
+ grub_elf32_phdr_iterate (elf, filename, grub_elf32_calcsize, &ctx);
if (base)
*base = 0;
- if (nr_phdrs == 0)
+ if (ctx.nr_phdrs == 0)
{
grub_error (GRUB_ERR_BAD_OS, "no program headers present");
return 0;
}
- if (segments_end < segments_start)
+ if (ctx.segments_end < ctx.segments_start)
{
/* Very bad addresses. */
grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses");
@@ -226,76 +235,87 @@ grub_elf32_size (grub_elf_t elf, const char *filename,
}
if (base)
- *base = segments_start;
+ *base = ctx.segments_start;
if (max_align)
- *max_align = curr_align;
- return segments_end - segments_start;
+ *max_align = ctx.curr_align;
+ return ctx.segments_end - ctx.segments_start;
}
-/* Load every loadable segment into memory specified by `_load_hook'. */
-grub_err_t
-grub_elf32_load (grub_elf_t _elf, const char *filename,
- grub_elf32_load_hook_t _load_hook,
- grub_addr_t *base, grub_size_t *size)
+struct grub_elf32_load_ctx
{
- grub_addr_t load_base = (grub_addr_t) -1ULL;
- grub_size_t load_size = 0;
- grub_err_t err;
+ const char *filename;
+ grub_elf32_load_hook_t load_hook;
+ grub_addr_t load_base;
+ grub_size_t load_size;
+};
+
+static int
+grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *data)
+{
+ struct grub_elf32_load_ctx *ctx = data;
+ grub_addr_t load_addr;
+ int do_load = 1;
- auto int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook);
- int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook)
- {
- grub_elf32_load_hook_t load_hook = (grub_elf32_load_hook_t) hook;
- grub_addr_t load_addr;
- int do_load = 1;
+ load_addr = phdr->p_paddr;
+ if (ctx->load_hook && ctx->load_hook (phdr, &load_addr, &do_load))
+ return 1;
- load_addr = phdr->p_paddr;
- if (load_hook && load_hook (phdr, &load_addr, &do_load))
- return 1;
+ if (! do_load)
+ return 0;
- if (! do_load)
- return 0;
+ if (load_addr < ctx->load_base)
+ ctx->load_base = load_addr;
- if (load_addr < load_base)
- load_base = load_addr;
+ grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
+ (unsigned long long) load_addr,
+ (unsigned long long) phdr->p_memsz);
- grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
- (unsigned long long) load_addr,
- (unsigned long long) phdr->p_memsz);
+ if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+ return grub_errno;
- if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
- return grub_errno;
+ if (phdr->p_filesz)
+ {
+ grub_ssize_t read;
+ read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+ if (read != (grub_ssize_t) phdr->p_filesz)
+ {
+ /* XXX How can we free memory from `ctx->load_hook'? */
+ if (!grub_errno)
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+ ctx->filename);
+ return grub_errno;
+ }
+ }
- if (phdr->p_filesz)
- {
- grub_ssize_t read;
- read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
- if (read != (grub_ssize_t) phdr->p_filesz)
- {
- /* XXX How can we free memory from `load_hook'? */
- if (!grub_errno)
- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
- filename);
- return grub_errno;
- }
- }
-
- if (phdr->p_filesz < phdr->p_memsz)
- grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
- 0, phdr->p_memsz - phdr->p_filesz);
-
- load_size += phdr->p_memsz;
+ if (phdr->p_filesz < phdr->p_memsz)
+ grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+ 0, phdr->p_memsz - phdr->p_filesz);
- return 0;
- }
+ ctx->load_size += phdr->p_memsz;
+
+ return 0;
+}
+
+/* Load every loadable segment into memory specified by `_load_hook'. */
+grub_err_t
+grub_elf32_load (grub_elf_t elf, const char *filename,
+ grub_elf32_load_hook_t load_hook,
+ grub_addr_t *base, grub_size_t *size)
+{
+ struct grub_elf32_load_ctx ctx = {
+ .filename = filename,
+ .load_hook = load_hook,
+ .load_base = (grub_addr_t) -1ULL,
+ .load_size = 0
+ };
+ grub_err_t err;
- err = grub_elf32_phdr_iterate (_elf, filename,
- grub_elf32_load_segment, _load_hook);
+ err = grub_elf32_phdr_iterate (elf, filename, grub_elf32_load_segment, &ctx);
if (base)
- *base = load_base;
+ *base = ctx.load_base;
if (size)
- *size = load_size;
+ *size = ctx.load_size;
return err;
}
@@ -339,8 +359,7 @@ grub_elf64_load_phdrs (grub_elf_t elf, const char *filename)
grub_err_t
grub_elf64_phdr_iterate (grub_elf_t elf,
const char *filename,
- int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *),
- void *hook_arg)
+ grub_elf64_phdr_iterate_hook_t hook, void *hook_arg)
{
Elf64_Phdr *phdrs;
unsigned int i;
@@ -367,48 +386,58 @@ grub_elf64_phdr_iterate (grub_elf_t elf,
return grub_errno;
}
+struct grub_elf64_size_ctx
+{
+ Elf64_Addr segments_start, segments_end;
+ int nr_phdrs;
+ grub_uint64_t curr_align;
+};
+
+/* Run through the program headers to calculate the total memory size we
+ * should claim. */
+static int
+grub_elf64_calcsize (grub_elf_t _elf __attribute__ ((unused)),
+ Elf64_Phdr *phdr, void *data)
+{
+ struct grub_elf64_size_ctx *ctx = data;
+
+ /* Only consider loadable segments. */
+ if (phdr->p_type != PT_LOAD)
+ return 0;
+ ctx->nr_phdrs++;
+ if (phdr->p_paddr < ctx->segments_start)
+ ctx->segments_start = phdr->p_paddr;
+ if (phdr->p_paddr + phdr->p_memsz > ctx->segments_end)
+ ctx->segments_end = phdr->p_paddr + phdr->p_memsz;
+ if (ctx->curr_align < phdr->p_align)
+ ctx->curr_align = phdr->p_align;
+ return 0;
+}
+
/* Calculate the amount of memory spanned by the segments. */
grub_size_t
grub_elf64_size (grub_elf_t elf, const char *filename,
Elf64_Addr *base, grub_uint64_t *max_align)
{
- Elf64_Addr segments_start = (Elf64_Addr) -1;
- Elf64_Addr segments_end = 0;
- int nr_phdrs = 0;
- grub_uint64_t curr_align = 1;
-
- /* Run through the program headers to calculate the total memory size we
- * should claim. */
- auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg);
- int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
- Elf64_Phdr *phdr,
- void *_arg __attribute__ ((unused)))
- {
- /* Only consider loadable segments. */
- if (phdr->p_type != PT_LOAD)
- return 0;
- nr_phdrs++;
- if (phdr->p_paddr < segments_start)
- segments_start = phdr->p_paddr;
- if (phdr->p_paddr + phdr->p_memsz > segments_end)
- segments_end = phdr->p_paddr + phdr->p_memsz;
- if (curr_align < phdr->p_align)
- curr_align = phdr->p_align;
- return 0;
- }
+ struct grub_elf64_size_ctx ctx = {
+ .segments_start = (Elf64_Addr) -1,
+ .segments_end = 0,
+ .nr_phdrs = 0,
+ .curr_align = 1
+ };
- grub_elf64_phdr_iterate (elf, filename, calcsize, 0);
+ grub_elf64_phdr_iterate (elf, filename, grub_elf64_calcsize, &ctx);
if (base)
*base = 0;
- if (nr_phdrs == 0)
+ if (ctx.nr_phdrs == 0)
{
grub_error (GRUB_ERR_BAD_OS, "no program headers present");
return 0;
}
- if (segments_end < segments_start)
+ if (ctx.segments_end < ctx.segments_start)
{
/* Very bad addresses. */
grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses");
@@ -416,77 +445,87 @@ grub_elf64_size (grub_elf_t elf, const char *filename,
}
if (base)
- *base = segments_start;
+ *base = ctx.segments_start;
if (max_align)
- *max_align = curr_align;
- return segments_end - segments_start;
+ *max_align = ctx.curr_align;
+ return ctx.segments_end - ctx.segments_start;
}
-/* Load every loadable segment into memory specified by `_load_hook'. */
-grub_err_t
-grub_elf64_load (grub_elf_t _elf, const char *filename,
- grub_elf64_load_hook_t _load_hook,
- grub_addr_t *base, grub_size_t *size)
+struct grub_elf64_load_ctx
{
- grub_addr_t load_base = (grub_addr_t) -1ULL;
- grub_size_t load_size = 0;
- grub_err_t err;
+ const char *filename;
+ grub_elf64_load_hook_t load_hook;
+ grub_addr_t load_base;
+ grub_size_t load_size;
+};
+
+static int
+grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, void *data)
+{
+ struct grub_elf64_load_ctx *ctx = data;
+ grub_addr_t load_addr;
+ int do_load = 1;
- auto int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr,
- void *hook);
- int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, void *hook)
- {
- grub_elf64_load_hook_t load_hook = (grub_elf64_load_hook_t) hook;
- grub_addr_t load_addr;
- int do_load = 1;
+ load_addr = phdr->p_paddr;
+ if (ctx->load_hook && ctx->load_hook (phdr, &load_addr, &do_load))
+ return 1;
- load_addr = phdr->p_paddr;
- if (load_hook && load_hook (phdr, &load_addr, &do_load))
- return 1;
+ if (! do_load)
+ return 0;
- if (! do_load)
- return 0;
+ if (load_addr < ctx->load_base)
+ ctx->load_base = load_addr;
- if (load_addr < load_base)
- load_base = load_addr;
+ grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
+ (unsigned long long) load_addr,
+ (unsigned long long) phdr->p_memsz);
- grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
- (unsigned long long) load_addr,
- (unsigned long long) phdr->p_memsz);
+ if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+ return grub_errno;
- if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
- return grub_errno;
+ if (phdr->p_filesz)
+ {
+ grub_ssize_t read;
+ read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+ if (read != (grub_ssize_t) phdr->p_filesz)
+ {
+ /* XXX How can we free memory from `ctx->load_hook'? */
+ if (!grub_errno)
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+ ctx->filename);
+ return grub_errno;
+ }
+ }
- if (phdr->p_filesz)
- {
- grub_ssize_t read;
- read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
- if (read != (grub_ssize_t) phdr->p_filesz)
- {
- /* XXX How can we free memory from `load_hook'? */
- if (!grub_errno)
- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
- filename);
- return grub_errno;
- }
- }
-
- if (phdr->p_filesz < phdr->p_memsz)
- grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
- 0, phdr->p_memsz - phdr->p_filesz);
-
- load_size += phdr->p_memsz;
+ if (phdr->p_filesz < phdr->p_memsz)
+ grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+ 0, phdr->p_memsz - phdr->p_filesz);
- return 0;
- }
+ ctx->load_size += phdr->p_memsz;
+
+ return 0;
+}
+
+/* Load every loadable segment into memory specified by `_load_hook'. */
+grub_err_t
+grub_elf64_load (grub_elf_t elf, const char *filename,
+ grub_elf64_load_hook_t load_hook,
+ grub_addr_t *base, grub_size_t *size)
+{
+ struct grub_elf64_load_ctx ctx = {
+ .filename = filename,
+ .load_hook = load_hook,
+ .load_base = (grub_addr_t) -1ULL,
+ .load_size = 0
+ };
+ grub_err_t err;
- err = grub_elf64_phdr_iterate (_elf, filename,
- grub_elf64_load_segment, _load_hook);
+ err = grub_elf64_phdr_iterate (elf, filename, grub_elf64_load_segment, &ctx);
if (base)
- *base = load_base;
+ *base = ctx.load_base;
if (size)
- *size = load_size;
+ *size = ctx.load_size;
return err;
}
diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c
index b8c3766..92ce1d9 100644
--- a/grub-core/kern/emu/hostdisk.c
+++ b/grub-core/kern/emu/hostdisk.c
@@ -223,7 +223,7 @@ find_free_slot (void)
}
static int
-grub_util_biosdisk_iterate (int (*hook) (const char *name),
+grub_util_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull)
{
unsigned i;
@@ -232,7 +232,7 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name),
return 0;
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
- if (map[i].drive && hook (map[i].drive))
+ if (map[i].drive && hook (map[i].drive, hook_data))
return 1;
return 0;
@@ -1339,7 +1339,7 @@ read_device_map (const char *dev_map)
{
map[drive].device = xmalloc (PATH_MAX);
if (! realpath (p, map[drive].device))
- grub_util_error (_("failed to get canonical path of %s"), p);
+ grub_util_error (_("failed to get canonical path of `%s'"), p);
}
else
#endif
diff --git a/grub-core/kern/emu/hostfs.c b/grub-core/kern/emu/hostfs.c
index 3cb089c..46bf5e8 100644
--- a/grub-core/kern/emu/hostfs.c
+++ b/grub-core/kern/emu/hostfs.c
@@ -65,8 +65,7 @@ struct grub_hostfs_data
static grub_err_t
grub_hostfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info))
+ grub_fs_dir_hook_t hook, void *hook_data)
{
DIR *dir;
@@ -91,7 +90,7 @@ grub_hostfs_dir (grub_device_t device, const char *path,
break;
info.dir = !! is_dir (path, de->d_name);
- hook (de->d_name, &info);
+ hook (de->d_name, &info, hook_data);
}
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
index 495326f..d2a6317 100644
--- a/grub-core/kern/file.c
+++ b/grub-core/kern/file.c
@@ -107,7 +107,7 @@ grub_file_open (const char *name)
if (grub_file_filters_enabled[filter])
{
last_file = file;
- file = grub_file_filters_enabled[filter] (file);
+ file = grub_file_filters_enabled[filter] (file, name);
}
if (!file)
grub_file_close (last_file);
diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c
index 51d89d1..9085895 100644
--- a/grub-core/kern/fs.c
+++ b/grub-core/kern/fs.c
@@ -32,18 +32,19 @@ grub_fs_t grub_fs_list = 0;
grub_fs_autoload_hook_t grub_fs_autoload_hook = 0;
+/* Helper for grub_fs_probe. */
+static int
+probe_dummy_iter (const char *filename __attribute__ ((unused)),
+ const struct grub_dirhook_info *info __attribute__ ((unused)),
+ void *data __attribute__ ((unused)))
+{
+ return 1;
+}
+
grub_fs_t
grub_fs_probe (grub_device_t device)
{
grub_fs_t p;
- auto int dummy_func (const char *filename,
- const struct grub_dirhook_info *info);
-
- int dummy_func (const char *filename __attribute__ ((unused)),
- const struct grub_dirhook_info *info __attribute__ ((unused)))
- {
- return 1;
- }
if (device->disk)
{
@@ -69,7 +70,7 @@ grub_fs_probe (grub_device_t device)
}
else
#endif
- (p->dir) (device, "/", dummy_func);
+ (p->dir) (device, "/", probe_dummy_iter, NULL);
if (grub_errno == GRUB_ERR_NONE)
return p;
@@ -93,7 +94,7 @@ grub_fs_probe (grub_device_t device)
{
p = grub_fs_list;
- (p->dir) (device, "/", dummy_func);
+ (p->dir) (device, "/", probe_dummy_iter, NULL);
if (grub_errno == GRUB_ERR_NONE)
{
count--;
diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c
index 52fbba4..48fd1a6 100644
--- a/grub-core/kern/i386/coreboot/init.c
+++ b/grub-core/kern/i386/coreboot/init.c
@@ -57,6 +57,39 @@ grub_addr_t grub_modbase;
grub_addr_t grub_modbase = ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN);
#endif
+/* Helper for grub_machine_init. */
+static int
+heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data __attribute__ ((unused)))
+{
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+ /* Restrict ourselves to 32-bit memory space. */
+ if (addr > GRUB_ULONG_MAX)
+ return 0;
+ if (addr + size > GRUB_ULONG_MAX)
+ size = GRUB_ULONG_MAX - addr;
+#endif
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+
+ /* Avoid the lower memory. */
+ if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE)
+ {
+ if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE)
+ return 0;
+ else
+ {
+ size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr;
+ addr = GRUB_MEMORY_MACHINE_LOWER_SIZE;
+ }
+ }
+
+ grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
+
+ return 0;
+}
+
void
grub_machine_init (void)
{
@@ -68,43 +101,10 @@ grub_machine_init (void)
/* Initialize the console as early as possible. */
grub_vga_text_init ();
- auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
-#if GRUB_CPU_SIZEOF_VOID_P == 4
- /* Restrict ourselves to 32-bit memory space. */
- if (addr > GRUB_ULONG_MAX)
- return 0;
- if (addr + size > GRUB_ULONG_MAX)
- size = GRUB_ULONG_MAX - addr;
-#endif
-
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
-
- /* Avoid the lower memory. */
- if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE)
- {
- if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE)
- return 0;
- else
- {
- size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr;
- addr = GRUB_MEMORY_MACHINE_LOWER_SIZE;
- }
- }
-
- grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
-
- return 0;
- }
-
#if defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
grub_machine_mmap_init ();
#endif
- grub_machine_mmap_iterate (heap_init);
+ grub_machine_mmap_iterate (heap_init, NULL);
grub_tsc_init ();
}
diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c
index 8b0b202..ae4af08 100644
--- a/grub-core/kern/i386/coreboot/mmap.c
+++ b/grub-core/kern/i386/coreboot/mmap.c
@@ -22,21 +22,24 @@
#include <grub/err.h>
#include <grub/misc.h>
+/* Helper for grub_linuxbios_table_iterate. */
+static int
+check_signature (grub_linuxbios_table_header_t tbl_header)
+{
+ if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
+ return 1;
+
+ return 0;
+}
+
static grub_err_t
-grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t))
+grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t,
+ void *),
+ void *hook_data)
{
grub_linuxbios_table_header_t table_header;
grub_linuxbios_table_item_t table_item;
- auto int check_signature (grub_linuxbios_table_header_t);
- int check_signature (grub_linuxbios_table_header_t tbl_header)
- {
- if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
- return 1;
-
- return 0;
- }
-
/* Assuming table_header is aligned to its size (8 bytes). */
for (table_header = (grub_linuxbios_table_header_t) 0x500;
@@ -67,42 +70,54 @@ signature_found:
*(grub_uint64_t *) (table_item + 1);
goto signature_found;
}
- if (hook (table_item))
+ if (hook (table_item, hook_data))
return 1;
}
return 0;
}
-grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+/* Context for grub_machine_mmap_iterate. */
+struct grub_machine_mmap_iterate_ctx
{
- mem_region_t mem_region;
+ grub_memory_hook_t hook;
+ void *hook_data;
+};
- auto int iterate_linuxbios_table (grub_linuxbios_table_item_t);
- int iterate_linuxbios_table (grub_linuxbios_table_item_t table_item)
- {
- if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY)
- return 0;
-
- mem_region =
- (mem_region_t) ((long) table_item +
- sizeof (struct grub_linuxbios_table_item));
- while ((long) mem_region < (long) table_item + (long) table_item->size)
- {
- if (hook (mem_region->addr, mem_region->size,
- /* Multiboot mmaps match with the coreboot mmap definition.
- Therefore, we can just pass type through. */
- mem_region->type))
- return 1;
-
- mem_region++;
- }
+/* Helper for grub_machine_mmap_iterate. */
+static int
+iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
+{
+ struct grub_machine_mmap_iterate_ctx *ctx = data;
+ mem_region_t mem_region;
+ if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY)
return 0;
- }
- grub_linuxbios_table_iterate (iterate_linuxbios_table);
+ mem_region =
+ (mem_region_t) ((long) table_item +
+ sizeof (struct grub_linuxbios_table_item));
+ while ((long) mem_region < (long) table_item + (long) table_item->size)
+ {
+ if (ctx->hook (mem_region->addr, mem_region->size,
+ /* Multiboot mmaps match with the coreboot mmap
+ definition. Therefore, we can just pass type
+ through. */
+ mem_region->type, ctx->hook_data))
+ return 1;
+
+ mem_region++;
+ }
+
+ return 0;
+}
+
+grub_err_t
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+{
+ struct grub_machine_mmap_iterate_ctx ctx = { hook, hook_data };
+
+ grub_linuxbios_table_iterate (iterate_linuxbios_table, &ctx);
return 0;
}
diff --git a/grub-core/kern/i386/multiboot_mmap.c b/grub-core/kern/i386/multiboot_mmap.c
index 1cb422f..e8f4f34 100644
--- a/grub-core/kern/i386/multiboot_mmap.c
+++ b/grub-core/kern/i386/multiboot_mmap.c
@@ -57,13 +57,13 @@ grub_machine_mmap_init (void)
}
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
struct multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr;
while ((unsigned long) entry < kern_multiboot_info.mmap_addr + kern_multiboot_info.mmap_length)
{
- if (hook (entry->addr, entry->len, entry->type))
+ if (hook (entry->addr, entry->len, entry->type, hook_data))
break;
entry = (void *) ((grub_addr_t) entry + entry->size + sizeof (entry->size));
diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c
index 0841d8b..7d8b12c 100644
--- a/grub-core/kern/i386/pc/init.c
+++ b/grub-core/kern/i386/pc/init.c
@@ -154,6 +154,36 @@ compact_mem_regions (void)
grub_addr_t grub_modbase;
extern grub_uint8_t _start[], _edata[];
+/* Helper for grub_machine_init. */
+static int
+mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type,
+ void *data __attribute__ ((unused)))
+{
+ /* Avoid the lower memory. */
+ if (addr < 0x100000)
+ {
+ if (size <= 0x100000 - addr)
+ return 0;
+
+ size -= 0x100000 - addr;
+ addr = 0x100000;
+ }
+
+ /* Ignore >4GB. */
+ if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE)
+ {
+ grub_size_t len;
+
+ len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
+ ? 0xFFFFFFFF - addr
+ : size);
+ add_mem_region (addr, len);
+ }
+
+ return 0;
+}
+
void
grub_machine_init (void)
{
@@ -188,36 +218,7 @@ grub_machine_init (void)
grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
#endif
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- /* Avoid the lower memory. */
- if (addr < 0x100000)
- {
- if (size <= 0x100000 - addr)
- return 0;
-
- size -= 0x100000 - addr;
- addr = 0x100000;
- }
-
- /* Ignore >4GB. */
- if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE)
- {
- grub_size_t len;
-
- len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
- ? 0xFFFFFFFF - addr
- : size);
- add_mem_region (addr, len);
- }
-
- return 0;
- }
-
- grub_machine_mmap_iterate (hook);
+ grub_machine_mmap_iterate (mmap_iterate_hook, NULL);
compact_mem_regions ();
diff --git a/grub-core/kern/i386/pc/mmap.c b/grub-core/kern/i386/pc/mmap.c
index 480ffa9..7e5feea 100644
--- a/grub-core/kern/i386/pc/mmap.c
+++ b/grub-core/kern/i386/pc/mmap.c
@@ -139,7 +139,7 @@ grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
}
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
grub_uint32_t cont;
struct grub_machine_mmap_entry *entry
@@ -156,7 +156,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
if (hook (entry->addr, entry->len,
/* GRUB mmaps have been defined to match with the E820 definition.
Therefore, we can just pass type through. */
- ((entry->type <= GRUB_MACHINE_MEMORY_BADRAM) && (entry->type >= GRUB_MACHINE_MEMORY_AVAILABLE)) ? entry->type : GRUB_MEMORY_RESERVED))
+ ((entry->type <= GRUB_MACHINE_MEMORY_BADRAM) && (entry->type >= GRUB_MACHINE_MEMORY_AVAILABLE)) ? entry->type : GRUB_MEMORY_RESERVED,
+ hook_data))
break;
if (! cont)
@@ -172,18 +173,19 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
if (hook (0x0, ((grub_uint32_t) grub_get_conv_memsize ()) << 10,
- GRUB_MEMORY_AVAILABLE))
+ GRUB_MEMORY_AVAILABLE, hook_data))
return 0;
if (eisa_mmap)
{
if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10,
- GRUB_MEMORY_AVAILABLE) == 0)
- hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE);
+ GRUB_MEMORY_AVAILABLE, hook_data) == 0)
+ hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE,
+ hook_data);
}
else
hook (0x100000, ((grub_uint32_t) grub_get_ext_memsize ()) << 10,
- GRUB_MEMORY_AVAILABLE);
+ GRUB_MEMORY_AVAILABLE, hook_data);
}
return 0;
diff --git a/grub-core/kern/i386/pit.c b/grub-core/kern/i386/pit.c
index 82a17d3..092481a 100644
--- a/grub-core/kern/i386/pit.c
+++ b/grub-core/kern/i386/pit.c
@@ -20,37 +20,30 @@
#include <grub/i386/io.h>
#include <grub/i386/pit.h>
-#define TIMER2_REG_CONTROL 0x42
-#define TIMER_REG_COMMAND 0x43
-#define TIMER2_REG_LATCH 0x61
-
-#define TIMER2_SELECT 0x80
-#define TIMER_ENABLE_LSB 0x20
-#define TIMER_ENABLE_MSB 0x10
-#define TIMER2_LATCH 0x20
-#define TIMER2_SPEAKER 0x02
-#define TIMER2_GATE 0x01
-
void
grub_pit_wait (grub_uint16_t tics)
{
/* Disable timer2 gate and speaker. */
- grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE),
- TIMER2_REG_LATCH);
+ grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
+ & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2),
+ GRUB_PIT_SPEAKER_PORT);
/* Set tics. */
- grub_outb (TIMER2_SELECT | TIMER_ENABLE_LSB | TIMER_ENABLE_MSB, TIMER_REG_COMMAND);
- grub_outb (tics & 0xff, TIMER2_REG_CONTROL);
- grub_outb (tics >> 8, TIMER2_REG_CONTROL);
+ grub_outb (GRUB_PIT_CTRL_SELECT_2 | GRUB_PIT_CTRL_READLOAD_WORD,
+ GRUB_PIT_CTRL);
+ grub_outb (tics & 0xff, GRUB_PIT_COUNTER_2);
+ grub_outb (tics >> 8, GRUB_PIT_COUNTER_2);
/* Enable timer2 gate, keep speaker disabled. */
- grub_outb ((grub_inb (TIMER2_REG_LATCH) & ~ TIMER2_SPEAKER) | TIMER2_GATE,
- TIMER2_REG_LATCH);
+ grub_outb ((grub_inb (GRUB_PIT_SPEAKER_PORT) & ~ GRUB_PIT_SPK_DATA)
+ | GRUB_PIT_SPK_TMR2,
+ GRUB_PIT_SPEAKER_PORT);
/* Wait. */
- while ((grub_inb (TIMER2_REG_LATCH) & TIMER2_LATCH) == 0x00);
+ while ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00);
/* Disable timer2 gate and speaker. */
- grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE),
- TIMER2_REG_LATCH);
+ grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
+ & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2),
+ GRUB_PIT_SPEAKER_PORT);
}
diff --git a/grub-core/kern/i386/qemu/mmap.c b/grub-core/kern/i386/qemu/mmap.c
index ffb61a4..f449637 100644
--- a/grub-core/kern/i386/qemu/mmap.c
+++ b/grub-core/kern/i386/qemu/mmap.c
@@ -69,38 +69,38 @@ grub_machine_mmap_init (void)
}
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
if (hook (0x0,
(grub_addr_t) _start,
- GRUB_MEMORY_AVAILABLE))
+ GRUB_MEMORY_AVAILABLE, hook_data))
return 1;
if (hook ((grub_addr_t) _end,
0xa0000 - (grub_addr_t) _end,
- GRUB_MEMORY_AVAILABLE))
+ GRUB_MEMORY_AVAILABLE, hook_data))
return 1;
if (hook (GRUB_MEMORY_MACHINE_UPPER,
0x100000 - GRUB_MEMORY_MACHINE_UPPER,
- GRUB_MEMORY_RESERVED))
+ GRUB_MEMORY_RESERVED, hook_data))
return 1;
/* Everything else is free. */
if (hook (0x100000,
min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000,
- GRUB_MEMORY_AVAILABLE))
+ GRUB_MEMORY_AVAILABLE, hook_data))
return 1;
/* Protect boot.img, which contains the gdt. It is mapped at the top of memory
(it is also mapped below 0x100000, but we already reserved that area). */
if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE,
GRUB_BOOT_MACHINE_SIZE,
- GRUB_MEMORY_RESERVED))
+ GRUB_MEMORY_RESERVED, hook_data))
return 1;
if (above_4g != 0 && hook (0x100000000ULL, above_4g,
- GRUB_MEMORY_AVAILABLE))
+ GRUB_MEMORY_AVAILABLE, hook_data))
return 1;
return 0;
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index 14dcdf0..0894cb6 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -156,74 +156,76 @@ grub_claim_heap (void)
+ GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
}
#else
+/* Helper for grub_claim_heap. */
+static int
+heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
+ void *data)
+{
+ unsigned long *total = data;
+
+ if (type != 1)
+ return 0;
+
+ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
+ {
+ if (addr + len <= 0x180000)
+ return 0;
+
+ if (addr < 0x180000)
+ {
+ len = addr + len - 0x180000;
+ addr = 0x180000;
+ }
+ }
+ len -= 1; /* Required for some firmware. */
+
+ /* Never exceed HEAP_MAX_SIZE */
+ if (*total + len > HEAP_MAX_SIZE)
+ len = HEAP_MAX_SIZE - *total;
+
+ /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */
+ if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */
+ (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */
+ (*total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */
+ len = HEAP_MAX_ADDR - addr;
+
+ /* In theory, firmware should already prevent this from happening by not
+ listing our own image in /memory/available. The check below is intended
+ as a safeguard in case that doesn't happen. However, it doesn't protect
+ us from corrupting our module area, which extends up to a
+ yet-undetermined region above _end. */
+ if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start))
+ {
+ grub_printf ("Warning: attempt to claim over our own code!\n");
+ len = 0;
+ }
+
+ if (len)
+ {
+ grub_err_t err;
+ /* Claim and use it. */
+ err = grub_claimmap (addr, len);
+ if (err)
+ return err;
+ grub_mm_init_region ((void *) (grub_addr_t) addr, len);
+ }
+
+ *total += len;
+ if (*total >= HEAP_MAX_SIZE)
+ return 1;
+
+ return 0;
+}
+
static void
grub_claim_heap (void)
{
unsigned long total = 0;
- auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len,
- grub_memory_type_t type);
- int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len,
- grub_memory_type_t type)
- {
- if (type != 1)
- return 0;
-
- if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
- {
- if (addr + len <= 0x180000)
- return 0;
-
- if (addr < 0x180000)
- {
- len = addr + len - 0x180000;
- addr = 0x180000;
- }
- }
- len -= 1; /* Required for some firmware. */
-
- /* Never exceed HEAP_MAX_SIZE */
- if (total + len > HEAP_MAX_SIZE)
- len = HEAP_MAX_SIZE - total;
-
- /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */
- if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */
- (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */
- (total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */
- len = HEAP_MAX_ADDR - addr;
-
- /* In theory, firmware should already prevent this from happening by not
- listing our own image in /memory/available. The check below is intended
- as a safeguard in case that doesn't happen. However, it doesn't protect
- us from corrupting our module area, which extends up to a
- yet-undetermined region above _end. */
- if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start))
- {
- grub_printf ("Warning: attempt to claim over our own code!\n");
- len = 0;
- }
-
- if (len)
- {
- grub_err_t err;
- /* Claim and use it. */
- err = grub_claimmap (addr, len);
- if (err)
- return err;
- grub_mm_init_region ((void *) (grub_addr_t) addr, len);
- }
-
- total += len;
- if (total >= HEAP_MAX_SIZE)
- return 1;
-
- return 0;
- }
-
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
- heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1);
+ heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1, &total);
else
- grub_machine_mmap_iterate (heap_init);
+ grub_machine_mmap_iterate (heap_init, &total);
}
#endif
diff --git a/grub-core/kern/ieee1275/mmap.c b/grub-core/kern/ieee1275/mmap.c
index 2e4e085..911bb00 100644
--- a/grub-core/kern/ieee1275/mmap.c
+++ b/grub-core/kern/ieee1275/mmap.c
@@ -21,7 +21,7 @@
#include <grub/types.h>
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
grub_ieee1275_phandle_t root;
grub_ieee1275_phandle_t memory;
@@ -72,7 +72,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
if (size_cells == 2)
size = (size << 32) | available[i++];
- if (hook (address, size, GRUB_MEMORY_AVAILABLE))
+ if (hook (address, size, GRUB_MEMORY_AVAILABLE, hook_data))
break;
}
diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c
index 44b4171..f63ac6d 100644
--- a/grub-core/kern/mips/arc/init.c
+++ b/grub-core/kern/mips/arc/init.c
@@ -48,8 +48,7 @@ const char *type_names[] = {
static int
iterate_rec (const char *prefix, const struct grub_arc_component *parent,
- int (*hook) (const char *name,
- const struct grub_arc_component *comp),
+ grub_arc_iterate_devs_hook_t hook, void *hook_data,
int alt_names)
{
const struct grub_arc_component *comp;
@@ -67,12 +66,13 @@ iterate_rec (const char *prefix, const struct grub_arc_component *parent,
name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key);
if (!name)
return 1;
- if (hook (name, comp))
+ if (hook (name, comp, hook_data))
{
grub_free (name);
return 1;
}
- if (iterate_rec ((parent ? name : prefix), comp, hook, alt_names))
+ if (iterate_rec ((parent ? name : prefix), comp, hook, hook_data,
+ alt_names))
{
grub_free (name);
return 1;
@@ -83,15 +83,15 @@ iterate_rec (const char *prefix, const struct grub_arc_component *parent,
}
int
-grub_arc_iterate_devs (int (*hook) (const char *name,
- const struct grub_arc_component *comp),
+grub_arc_iterate_devs (grub_arc_iterate_devs_hook_t hook, void *hook_data,
int alt_names)
{
- return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, alt_names);
+ return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, hook_data,
+ alt_names);
}
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
struct grub_arc_memory_descriptor *cur = NULL;
while (1)
@@ -120,7 +120,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
break;
}
if (hook (((grub_uint64_t) cur->start_page) << 12,
- ((grub_uint64_t) cur->num_pages) << 12, type))
+ ((grub_uint64_t) cur->num_pages) << 12, type, hook_data))
return GRUB_ERR_NONE;
}
}
diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c
index 19f2d63..756439b 100644
--- a/grub-core/kern/mips/loongson/init.c
+++ b/grub-core/kern/mips/loongson/init.c
@@ -40,54 +40,56 @@
#include <grub/at_keyboard.h>
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20,
- GRUB_MEMORY_AVAILABLE);
+ GRUB_MEMORY_AVAILABLE, hook_data);
hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20,
- GRUB_MEMORY_AVAILABLE);
+ GRUB_MEMORY_AVAILABLE, hook_data);
return GRUB_ERR_NONE;
}
-static void
-init_pci (void)
+/* Helper for init_pci. */
+static int
+set_card (grub_pci_device_t dev, grub_pci_id_t pciid,
+ void *data __attribute__ ((unused)))
{
- auto int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid);
- int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid)
- {
- grub_pci_address_t addr;
- /* FIXME: autoscan for BARs and devices. */
- switch (pciid)
- {
- case GRUB_LOONGSON_OHCI_PCIID:
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
- grub_pci_write (addr, 0x5025000);
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
- grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE
- | GRUB_PCI_COMMAND_PARITY_ERROR
- | GRUB_PCI_COMMAND_BUS_MASTER
- | GRUB_PCI_COMMAND_MEM_ENABLED);
+ grub_pci_address_t addr;
+ /* FIXME: autoscan for BARs and devices. */
+ switch (pciid)
+ {
+ case GRUB_LOONGSON_OHCI_PCIID:
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+ grub_pci_write (addr, 0x5025000);
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
+ grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE
+ | GRUB_PCI_COMMAND_PARITY_ERROR
+ | GRUB_PCI_COMMAND_BUS_MASTER
+ | GRUB_PCI_COMMAND_MEM_ENABLED);
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
- grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES);
- break;
- case GRUB_LOONGSON_EHCI_PCIID:
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
- grub_pci_write (addr, 0x5026000);
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
- grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE
- | GRUB_PCI_COMMAND_PARITY_ERROR
- | GRUB_PCI_COMMAND_BUS_MASTER
- | GRUB_PCI_COMMAND_MEM_ENABLED);
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
+ grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES);
+ break;
+ case GRUB_LOONGSON_EHCI_PCIID:
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+ grub_pci_write (addr, 0x5026000);
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
+ grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE
+ | GRUB_PCI_COMMAND_PARITY_ERROR
+ | GRUB_PCI_COMMAND_BUS_MASTER
+ | GRUB_PCI_COMMAND_MEM_ENABLED);
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
- grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT)
- | GRUB_PCI_STATUS_CAPABILITIES);
- break;
- }
- return 0;
- }
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
+ grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT)
+ | GRUB_PCI_STATUS_CAPABILITIES);
+ break;
+ }
+ return 0;
+}
+static void
+init_pci (void)
+{
*((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO) = 0x8000000c;
*((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) = 0xffffffff;
@@ -110,7 +112,7 @@ init_pci (void)
*((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER
+ GRUB_PCI_REG_ADDRESS_REG1)) = 0;
- grub_pci_iterate (set_card);
+ grub_pci_iterate (set_card, NULL);
}
void
diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c
index 782f17f..aa414eb 100644
--- a/grub-core/kern/mips/qemu_mips/init.c
+++ b/grub-core/kern/mips/qemu_mips/init.c
@@ -92,9 +92,9 @@ grub_halt (void)
}
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
- hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE);
+ hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE, hook_data);
return GRUB_ERR_NONE;
}
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index 95d4624..c3203a0 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -741,23 +741,26 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a
if (*fmt && *fmt =='-')
fmt++;
- while (*fmt && grub_isdigit (*fmt))
- fmt++;
-
- if (*fmt && *fmt =='.')
- fmt++;
+ p = fmt;
while (*fmt && grub_isdigit (*fmt))
fmt++;
- p = fmt;
-
if (*fmt && *fmt == '$')
{
curn = grub_strtoull (p, 0, 10) - 1;
fmt++;
}
+ if (*fmt && *fmt =='-')
+ fmt++;
+
+ while (*fmt && grub_isdigit (*fmt))
+ fmt++;
+
+ if (*fmt && *fmt =='.')
+ fmt++;
+
while (*fmt && grub_isdigit (*fmt))
fmt++;
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
index 9213caa..b261fa0 100644
--- a/grub-core/kern/parser.c
+++ b/grub-core/kern/parser.c
@@ -96,8 +96,19 @@ grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result)
}
+/* Helper for grub_parser_split_cmdline. */
+static inline int
+check_varstate (grub_parser_state_t s)
+{
+ return (s == GRUB_PARSER_STATE_VARNAME
+ || s == GRUB_PARSER_STATE_VARNAME2
+ || s == GRUB_PARSER_STATE_QVARNAME
+ || s == GRUB_PARSER_STATE_QVARNAME2);
+}
+
grub_err_t
-grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
+grub_parser_split_cmdline (const char *cmdline,
+ grub_reader_getline_t getline, void *getline_data,
int *argc, char ***argv)
{
grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
@@ -111,16 +122,6 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
char *args;
int i;
- auto int check_varstate (grub_parser_state_t s);
-
- int check_varstate (grub_parser_state_t s)
- {
- return (s == GRUB_PARSER_STATE_VARNAME
- || s == GRUB_PARSER_STATE_VARNAME2
- || s == GRUB_PARSER_STATE_QVARNAME
- || s == GRUB_PARSER_STATE_QVARNAME2);
- }
-
auto void add_var (grub_parser_state_t newstate);
void add_var (grub_parser_state_t newstate)
@@ -149,7 +150,7 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
if (!rd || !*rd)
{
if (getline)
- getline (&rd, 1);
+ getline (&rd, 1, getline_data);
else
break;
}
@@ -232,36 +233,39 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
return 0;
}
+/* Helper for grub_parser_execute. */
+static grub_err_t
+grub_parser_execute_getline (char **line, int cont __attribute__ ((unused)),
+ void *data)
+{
+ char **source = data;
+ char *p;
+
+ if (!*source)
+ {
+ *line = 0;
+ return 0;
+ }
+
+ p = grub_strchr (*source, '\n');
+
+ if (p)
+ *line = grub_strndup (*source, p - *source);
+ else
+ *line = grub_strdup (*source);
+ *source = p ? p + 1 : 0;
+ return 0;
+}
+
grub_err_t
grub_parser_execute (char *source)
{
- auto grub_err_t getline (char **line, int cont);
- grub_err_t getline (char **line, int cont __attribute__ ((unused)))
- {
- char *p;
-
- if (!source)
- {
- *line = 0;
- return 0;
- }
-
- p = grub_strchr (source, '\n');
-
- if (p)
- *line = grub_strndup (source, p - source);
- else
- *line = grub_strdup (source);
- source = p ? p + 1 : 0;
- return 0;
- }
-
while (source)
{
char *line;
- getline (&line, 0);
- grub_rescue_parse_line (line, getline);
+ grub_parser_execute_getline (&line, 0, &source);
+ grub_rescue_parse_line (line, grub_parser_execute_getline, &source);
grub_free (line);
}
diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c
index 82ae9c8..e499147 100644
--- a/grub-core/kern/partition.c
+++ b/grub-core/kern/partition.c
@@ -59,39 +59,50 @@ grub_partition_check_containment (const grub_disk_t disk,
return 1;
}
-static grub_partition_t
-grub_partition_map_probe (const grub_partition_map_t partmap,
- grub_disk_t disk, int partnum)
+/* Context for grub_partition_map_probe. */
+struct grub_partition_map_probe_ctx
{
- grub_partition_t p = 0;
+ int partnum;
+ grub_partition_t p;
+};
- auto int find_func (grub_disk_t d, const grub_partition_t partition);
+/* Helper for grub_partition_map_probe. */
+static int
+probe_iter (grub_disk_t dsk, const grub_partition_t partition, void *data)
+{
+ struct grub_partition_map_probe_ctx *ctx = data;
- int find_func (grub_disk_t dsk,
- const grub_partition_t partition)
- {
- if (partnum != partition->number)
- return 0;
+ if (ctx->partnum != partition->number)
+ return 0;
- if (!(grub_partition_check_containment (dsk, partition)))
- return 0;
+ if (!(grub_partition_check_containment (dsk, partition)))
+ return 0;
- p = (grub_partition_t) grub_malloc (sizeof (*p));
- if (! p)
- return 1;
+ ctx->p = (grub_partition_t) grub_malloc (sizeof (*ctx->p));
+ if (! ctx->p)
+ return 1;
- grub_memcpy (p, partition, sizeof (*p));
- return 1;
- }
+ grub_memcpy (ctx->p, partition, sizeof (*ctx->p));
+ return 1;
+}
- partmap->iterate (disk, find_func);
+static grub_partition_t
+grub_partition_map_probe (const grub_partition_map_t partmap,
+ grub_disk_t disk, int partnum)
+{
+ struct grub_partition_map_probe_ctx ctx = {
+ .partnum = partnum,
+ .p = 0
+ };
+
+ partmap->iterate (disk, probe_iter, &ctx);
if (grub_errno)
goto fail;
- return p;
+ return ctx.p;
fail:
- grub_free (p);
+ grub_free (ctx.p);
return 0;
}
@@ -162,62 +173,71 @@ grub_partition_probe (struct grub_disk *disk, const char *str)
return part;
}
-int
-grub_partition_iterate (struct grub_disk *disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+/* Context for grub_partition_iterate. */
+struct grub_partition_iterate_ctx
{
- int ret = 0;
-
- auto int part_iterate (grub_disk_t dsk, const grub_partition_t p);
+ int ret;
+ grub_partition_iterate_hook_t hook;
+ void *hook_data;
+};
- int part_iterate (grub_disk_t dsk,
- const grub_partition_t partition)
- {
- struct grub_partition p = *partition;
+/* Helper for grub_partition_iterate. */
+static int
+part_iterate (grub_disk_t dsk, const grub_partition_t partition, void *data)
+{
+ struct grub_partition_iterate_ctx *ctx = data;
+ struct grub_partition p = *partition;
- if (!(grub_partition_check_containment (dsk, partition)))
- return 0;
+ if (!(grub_partition_check_containment (dsk, partition)))
+ return 0;
- p.parent = dsk->partition;
- dsk->partition = 0;
- if (hook (dsk, &p))
- {
- ret = 1;
- return 1;
- }
- if (p.start != 0)
- {
- const struct grub_partition_map *partmap;
- dsk->partition = &p;
- FOR_PARTITION_MAPS(partmap)
- {
- grub_err_t err;
- err = partmap->iterate (dsk, part_iterate);
- if (err)
- grub_errno = GRUB_ERR_NONE;
- if (ret)
- break;
- }
- }
- dsk->partition = p.parent;
- return ret;
+ p.parent = dsk->partition;
+ dsk->partition = 0;
+ if (ctx->hook (dsk, &p, ctx->hook_data))
+ {
+ ctx->ret = 1;
+ return 1;
}
-
- {
- const struct grub_partition_map *partmap;
- FOR_PARTITION_MAPS(partmap)
+ if (p.start != 0)
{
- grub_err_t err;
- err = partmap->iterate (disk, part_iterate);
- if (err)
- grub_errno = GRUB_ERR_NONE;
- if (ret)
- break;
+ const struct grub_partition_map *partmap;
+ dsk->partition = &p;
+ FOR_PARTITION_MAPS(partmap)
+ {
+ grub_err_t err;
+ err = partmap->iterate (dsk, part_iterate, ctx);
+ if (err)
+ grub_errno = GRUB_ERR_NONE;
+ if (ctx->ret)
+ break;
+ }
}
+ dsk->partition = p.parent;
+ return ctx->ret;
+}
+
+int
+grub_partition_iterate (struct grub_disk *disk,
+ grub_partition_iterate_hook_t hook, void *hook_data)
+{
+ struct grub_partition_iterate_ctx ctx = {
+ .ret = 0,
+ .hook = hook,
+ .hook_data = hook_data
+ };
+ const struct grub_partition_map *partmap;
+
+ FOR_PARTITION_MAPS(partmap)
+ {
+ grub_err_t err;
+ err = partmap->iterate (disk, part_iterate, &ctx);
+ if (err)
+ grub_errno = GRUB_ERR_NONE;
+ if (ctx.ret)
+ break;
}
- return ret;
+ return ctx.ret;
}
char *
diff --git a/grub-core/kern/rescue_parser.c b/grub-core/kern/rescue_parser.c
index 656342d..ab3d041 100644
--- a/grub-core/kern/rescue_parser.c
+++ b/grub-core/kern/rescue_parser.c
@@ -26,14 +26,16 @@
#include <grub/i18n.h>
grub_err_t
-grub_rescue_parse_line (char *line, grub_reader_getline_t getline)
+grub_rescue_parse_line (char *line,
+ grub_reader_getline_t getline, void *getline_data)
{
char *name;
int n;
grub_command_t cmd;
char **args;
- if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0)
+ if (grub_parser_split_cmdline (line, getline, getline_data, &n, &args)
+ || n < 0)
return grub_errno;
if (n == 0)
diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c
index 4587b94..dcd7d44 100644
--- a/grub-core/kern/rescue_reader.c
+++ b/grub-core/kern/rescue_reader.c
@@ -30,7 +30,8 @@ static char linebuf[GRUB_RESCUE_BUF_SIZE];
/* Prompt to input a command and read the line. */
static grub_err_t
-grub_rescue_read_line (char **line, int cont)
+grub_rescue_read_line (char **line, int cont,
+ void *data __attribute__ ((unused)))
{
int c;
int pos = 0;
@@ -87,11 +88,11 @@ grub_rescue_run (void)
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
- grub_rescue_read_line (&line, 0);
+ grub_rescue_read_line (&line, 0, NULL);
if (! line || line[0] == '\0')
continue;
- grub_rescue_parse_line (line, grub_rescue_read_line);
+ grub_rescue_parse_line (line, grub_rescue_read_line, NULL);
grub_free (line);
}
}
diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c
index 5014caf..34096bc 100644
--- a/grub-core/kern/term.c
+++ b/grub-core/kern/term.c
@@ -28,6 +28,10 @@ struct grub_term_input *grub_term_inputs_disabled;
struct grub_term_output *grub_term_outputs;
struct grub_term_input *grub_term_inputs;
+/* Current color state. */
+grub_uint8_t grub_term_normal_color;
+grub_uint8_t grub_term_highlight_color;
+
void (*grub_term_poll_usb) (void) = NULL;
void (*grub_net_poll_cards_idle) (void) = NULL;
diff --git a/grub-core/kern/uboot/hw.c b/grub-core/kern/uboot/hw.c
index 0bf64df..e818f74 100644
--- a/grub-core/kern/uboot/hw.c
+++ b/grub-core/kern/uboot/hw.c
@@ -94,7 +94,7 @@ grub_uboot_probe_hardware (void)
}
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
int i;
struct sys_info *si = uboot_get_sys_info ();
@@ -105,7 +105,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
/* Iterate and call `hook'. */
for (i = 0; i < si->mr_no; i++)
if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM)
- hook (si->mr[i].start, si->mr[i].size, GRUB_MEMORY_AVAILABLE);
+ hook (si->mr[i].start, si->mr[i].size, GRUB_MEMORY_AVAILABLE,
+ hook_data);
return GRUB_ERR_NONE;
}
diff --git a/grub-core/kern/vga_init.c b/grub-core/kern/vga_init.c
index 889d012..1119bb3 100644
--- a/grub-core/kern/vga_init.c
+++ b/grub-core/kern/vga_init.c
@@ -18,6 +18,7 @@
#ifndef __mips__
#include <grub/pci.h>
+#include <grub/mm.h>
#endif
#include <grub/machine/kernel.h>
#include <grub/misc.h>
@@ -87,38 +88,42 @@ load_palette (void)
grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b);
}
+#ifndef __mips__
+/* Helper for grub_qemu_init_cirrus. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)),
+ void *data __attribute__ ((unused)))
+{
+ grub_pci_address_t addr;
+ grub_uint32_t class;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ class = grub_pci_read (addr);
+
+ if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA)
+ return 0;
+
+ /* FIXME: chooose addresses dynamically. */
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+ grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH
+ | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32);
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
+ grub_pci_write (addr, 0xf2000000
+ | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32);
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
+ grub_pci_write (addr, GRUB_PCI_COMMAND_MEM_ENABLED
+ | GRUB_PCI_COMMAND_IO_ENABLED);
+
+ return 1;
+}
+#endif
+
void
grub_qemu_init_cirrus (void)
{
#ifndef __mips__
- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid);
- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
- {
- grub_pci_address_t addr;
- grub_uint32_t class;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
- class = grub_pci_read (addr);
-
- if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA)
- return 0;
-
- /* FIXME: chooose addresses dynamically. */
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
- grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH
- | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32);
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
- grub_pci_write (addr, 0xf2000000
- | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32);
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
- grub_pci_write (addr, GRUB_PCI_COMMAND_MEM_ENABLED
- | GRUB_PCI_COMMAND_IO_ENABLED);
-
- return 1;
- }
-
- grub_pci_iterate (find_card);
+ grub_pci_iterate (find_card, NULL);
#endif
grub_outb (GRUB_VGA_IO_MISC_COLOR,
diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
index b341885..a2d9416 100644
--- a/grub-core/lib/arg.c
+++ b/grub-core/lib/arg.c
@@ -34,25 +34,26 @@ static const struct grub_arg_option help_options[] =
{0, 0, 0, 0, 0, 0}
};
+/* Helper for find_short. */
static struct grub_arg_option *
-find_short (const struct grub_arg_option *options, char c)
+fnd_short (const struct grub_arg_option *opt, char c)
{
- struct grub_arg_option *found = 0;
- auto struct grub_arg_option *fnd_short (const struct grub_arg_option *opt);
-
- struct grub_arg_option *fnd_short (const struct grub_arg_option *opt)
+ while (opt->doc)
{
- while (opt->doc)
- {
- if (opt->shortarg == c)
- return (struct grub_arg_option *) opt;
- opt++;
- }
- return 0;
+ if (opt->shortarg == c)
+ return (struct grub_arg_option *) opt;
+ opt++;
}
+ return 0;
+}
+
+static struct grub_arg_option *
+find_short (const struct grub_arg_option *options, char c)
+{
+ struct grub_arg_option *found = 0;
if (options)
- found = fnd_short (options);
+ found = fnd_short (options, c);
if (! found)
{
@@ -74,29 +75,30 @@ find_short (const struct grub_arg_option *options, char c)
return found;
}
+/* Helper for find_long. */
static struct grub_arg_option *
-find_long (const struct grub_arg_option *options, const char *s, int len)
+fnd_long (const struct grub_arg_option *opt, const char *s, int len)
{
- struct grub_arg_option *found = 0;
- auto struct grub_arg_option *fnd_long (const struct grub_arg_option *opt);
-
- struct grub_arg_option *fnd_long (const struct grub_arg_option *opt)
+ while (opt->doc)
{
- while (opt->doc)
- {
- if (opt->longarg && ! grub_strncmp (opt->longarg, s, len) &&
- opt->longarg[len] == '\0')
- return (struct grub_arg_option *) opt;
- opt++;
- }
- return 0;
+ if (opt->longarg && ! grub_strncmp (opt->longarg, s, len) &&
+ opt->longarg[len] == '\0')
+ return (struct grub_arg_option *) opt;
+ opt++;
}
+ return 0;
+}
+
+static struct grub_arg_option *
+find_long (const struct grub_arg_option *options, const char *s, int len)
+{
+ struct grub_arg_option *found = 0;
if (options)
- found = fnd_long (options);
+ found = fnd_long (options, s, len);
if (! found)
- found = fnd_long (help_options);
+ found = fnd_long (help_options, s, len);
return found;
}
diff --git a/grub-core/lib/arm/libgcc.S b/grub-core/lib/arm/libgcc.S
index d0e7f6c..29fd857 100644
--- a/grub-core/lib/arm/libgcc.S
+++ b/grub-core/lib/arm/libgcc.S
@@ -257,32 +257,56 @@ FUNCTION(__aeabi_llsr)
@ r0 - *beg (inclusive)
@ r1 - *end (exclusive)
clean_dcache_range:
- @DCCMVAU
+ @ Clean data cache range for range to point-of-unification
+ ldr r2, dlinesz
1: cmp r0, r1
bge 2f
- mcr p15, 0, r0, c7, c11, 1
- add r0, r0, #32 @ assume 32-byte cache line
+#ifdef DEBUG
+ push {r0-r2, lr}
+ mov r1, r2
+ mov r2, r0
+ ldr r0, =dcstr
+ bl EXT_C(grub_printf)
+ pop {r0-r2, lr}
+#endif
+ mcr p15, 0, r0, c7, c11, 1 @ DCCMVAU
+ add r0, r0, r2 @ Next line
+ b 1b
2: dsb
bx lr
@ r0 - *beg (inclusive)
@ r1 - *end (exclusive)
invalidate_icache_range:
- @ICIMVAU
+ @ Invalidate instruction cache for range to point-of-unification
+ ldr r2, ilinesz
1: cmp r0, r1
bge 2f
- mcr p15, 0, r0, c7, c5, 1
- @BPIMVA
- mcr p15, 0, r0, c7, c5, 7
- add r0, r0, #32 @ assume 32-byte cache line
+#ifdef DEBUG
+ push {r0-r2, lr}
+ mov r1, r2
+ mov r2, r0
+ ldr r0, =icstr
+ bl EXT_C(grub_printf)
+ pop {r0-r2, lr}
+#endif
+ mcr p15, 0, r0, c7, c5, 1 @ ICIMVAU
+ add r0, r0, r2 @ Next line
b 1b
+ @ Branch predictor invalidate all
+2: mcr p15, 0, r0, c7, c5, 6 @ BPIALL
dsb
-2: isb
+ isb
bx lr
@void __clear_cache(char *beg, char *end);
FUNCTION(__clear_cache)
+ dmb
+ dsb
push {r4-r6, lr}
+ ldr r2, probed @ If first call, probe cache sizes
+ cmp r2, #0
+ bleq probe_caches @ This call corrupts r3
mov r4, r0
mov r5, r1
bl clean_dcache_range
@@ -291,6 +315,36 @@ FUNCTION(__clear_cache)
bl invalidate_icache_range
pop {r4-r6, pc}
+probe_caches:
+ push {r4-r6, lr}
+ mrc p15, 0, r4, c0, c0, 1 @ Read Cache Type Register
+ mov r5, #1
+ ubfx r6, r4, #16, #4 @ Extract min D-cache num word log2
+ add r6, r6, #2 @ words->bytes
+ lsl r6, r5, r6 @ Convert to num bytes
+ ldr r3, =dlinesz
+ str r6, [r3]
+ and r6, r4, #0xf @ Extract min I-cache num word log2
+ add r6, r6, #2 @ words->bytes
+ lsl r6, r5, r6 @ Convert to num bytes
+ ldr r3, =ilinesz
+ str r6, [r3]
+ ldr r3, =probed @ Flag cache probing done
+ str r5, [r3]
+ pop {r4-r6, pc}
+
+#ifdef DEBUG
+dcstr: .asciz "cleaning %d bytes of D cache @ 0x%08x\n"
+icstr: .asciz "invalidating %d bytes of I cache @ 0x%08x\n"
+#endif
+
+ .align 3
+probed: .long 0
+dlinesz:
+ .long 0
+ilinesz:
+ .long 0
+
@void grub_arch_sync_caches (void *address, grub_size_t len)
FUNCTION(grub_arch_sync_caches)
add r1, r0, r1
diff --git a/grub-core/lib/crc.c b/grub-core/lib/crc.c
index ffc3ef3..bf97cc6 100644
--- a/grub-core/lib/crc.c
+++ b/grub-core/lib/crc.c
@@ -22,25 +22,26 @@
static grub_uint32_t crc32c_table [256];
-static void
-init_crc32c_table (void)
+/* Helper for init_crc32c_table. */
+static grub_uint32_t
+reflect (grub_uint32_t ref, int len)
{
- auto grub_uint32_t reflect (grub_uint32_t ref, int len);
- grub_uint32_t reflect (grub_uint32_t ref, int len)
- {
- grub_uint32_t result = 0;
- int i;
-
- for (i = 1; i <= len; i++)
- {
- if (ref & 1)
- result |= 1 << (len - i);
- ref >>= 1;
- }
+ grub_uint32_t result = 0;
+ int i;
- return result;
+ for (i = 1; i <= len; i++)
+ {
+ if (ref & 1)
+ result |= 1 << (len - i);
+ ref >>= 1;
}
+ return result;
+}
+
+static void
+init_crc32c_table (void)
+{
grub_uint32_t polynomial = 0x1edc6f41;
int i, j;
diff --git a/grub-core/lib/crc64.c b/grub-core/lib/crc64.c
index 4b1c92c..4960f3f 100644
--- a/grub-core/lib/crc64.c
+++ b/grub-core/lib/crc64.c
@@ -25,25 +25,26 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_uint64_t crc64_table [256];
-static void
-init_crc64_table (void)
+/* Helper for init_crc64_table. */
+static grub_uint64_t
+reflect (grub_uint64_t ref, int len)
{
- auto grub_uint64_t reflect (grub_uint64_t ref, int len);
- grub_uint64_t reflect (grub_uint64_t ref, int len)
- {
- grub_uint64_t result = 0;
- int i;
+ grub_uint64_t result = 0;
+ int i;
- for (i = 1; i <= len; i++)
- {
- if (ref & 1)
- result |= 1ULL << (len - i);
- ref >>= 1;
- }
-
- return result;
+ for (i = 1; i <= len; i++)
+ {
+ if (ref & 1)
+ result |= 1ULL << (len - i);
+ ref >>= 1;
}
+ return result;
+}
+
+static void
+init_crc64_table (void)
+{
grub_uint64_t polynomial = 0x42f0e1eba9ea3693ULL;
int i, j;
diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c
index f4b13ed..dce5eda 100644
--- a/grub-core/lib/crypto.c
+++ b/grub-core/lib/crypto.c
@@ -23,6 +23,7 @@
#include <grub/term.h>
#include <grub/dl.h>
#include <grub/i18n.h>
+#include <grub/env.h>
#ifdef GRUB_UTIL
#include <termios.h>
@@ -56,6 +57,38 @@ grub_burn_stack (grub_size_t size)
grub_burn_stack (size - sizeof (buf));
}
+void
+_gcry_burn_stack (int size)
+{
+ grub_burn_stack (size);
+}
+
+void __attribute__ ((noreturn))
+_gcry_assert_failed (const char *expr, const char *file, int line,
+ const char *func)
+
+{
+ grub_fatal ("assertion %s at %s:%d (%s) failed\n", expr, file, line, func);
+}
+
+
+void _gcry_log_error (const char *fmt, ...)
+{
+ va_list args;
+ const char *debug = grub_env_get ("debug");
+
+ if (! debug)
+ return;
+
+ if (grub_strword (debug, "all") || grub_strword (debug, "gcrypt"))
+ {
+ grub_printf ("gcrypt error: ");
+ va_start (args, fmt);
+ grub_vprintf (fmt, args);
+ va_end (args);
+ grub_refresh ();
+ }
+}
void
grub_cipher_register (gcry_cipher_spec_t *cipher)
@@ -477,3 +510,4 @@ grub_password_get (char buf[], unsigned buf_size)
return (key != '\e');
#endif
}
+
diff --git a/grub-core/lib/dtc/libfdt/fdt.c b/grub-core/lib/dtc/libfdt/fdt.c
index e56833a..e862734 100644
--- a/grub-core/lib/dtc/libfdt/fdt.c
+++ b/grub-core/lib/dtc/libfdt/fdt.c
@@ -55,168 +55,187 @@
#include "libfdt_internal.h"
-int fdt_check_header(const void *fdt)
+int
+fdt_check_header (const void *fdt)
{
- if (fdt_magic(fdt) == FDT_MAGIC) {
- /* Complete tree */
- if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
- /* Unfinished sequential-write blob */
- if (fdt_size_dt_struct(fdt) == 0)
- return -FDT_ERR_BADSTATE;
- } else {
- return -FDT_ERR_BADMAGIC;
- }
-
- return 0;
+ if (fdt_magic (fdt) == FDT_MAGIC)
+ {
+ /* Complete tree */
+ if (fdt_version (fdt) < FDT_FIRST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ if (fdt_last_comp_version (fdt) > FDT_LAST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ }
+ else if (fdt_magic (fdt) == FDT_SW_MAGIC)
+ {
+ /* Unfinished sequential-write blob */
+ if (fdt_size_dt_struct (fdt) == 0)
+ return -FDT_ERR_BADSTATE;
+ }
+ else
+ {
+ return -FDT_ERR_BADMAGIC;
+ }
+
+ return 0;
}
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
+const void *
+fdt_offset_ptr (const void *fdt, int offset, unsigned int len)
{
- const char *p;
+ const char *p;
- if (fdt_version(fdt) >= 0x11)
- if (((offset + len) < offset)
- || ((offset + len) > fdt_size_dt_struct(fdt)))
- return NULL;
+ if (fdt_version (fdt) >= 0x11)
+ if (((offset + len) < offset)
+ || ((offset + len) > fdt_size_dt_struct (fdt)))
+ return NULL;
- p = _fdt_offset_ptr(fdt, offset);
+ p = _fdt_offset_ptr (fdt, offset);
- if (p + len < p)
- return NULL;
- return p;
+ if (p + len < p)
+ return NULL;
+ return p;
}
-uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
+uint32_t
+fdt_next_tag (const void *fdt, int startoffset, int *nextoffset)
{
- const uint32_t *tagp, *lenp;
- uint32_t tag;
- int offset = startoffset;
- const char *p;
-
- *nextoffset = -FDT_ERR_TRUNCATED;
- tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
- if (!tagp)
- return FDT_END; /* premature end */
- tag = fdt32_to_cpu(*tagp);
- offset += FDT_TAGSIZE;
-
- *nextoffset = -FDT_ERR_BADSTRUCTURE;
- switch (tag) {
- case FDT_BEGIN_NODE:
- /* skip name */
- do {
- p = fdt_offset_ptr(fdt, offset++, 1);
- } while (p && (*p != '\0'));
- if (!p)
- return FDT_END; /* premature end */
- break;
-
- case FDT_PROP:
- lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
- if (!lenp)
- return FDT_END; /* premature end */
- /* skip-name offset, length and value */
- offset += sizeof(struct fdt_property) - FDT_TAGSIZE
- + fdt32_to_cpu(*lenp);
- break;
-
- case FDT_END:
- case FDT_END_NODE:
- case FDT_NOP:
- break;
-
- default:
- return FDT_END;
+ const uint32_t *tagp, *lenp;
+ uint32_t tag;
+ int offset = startoffset;
+ const char *p;
+
+ *nextoffset = -FDT_ERR_TRUNCATED;
+ tagp = fdt_offset_ptr (fdt, offset, FDT_TAGSIZE);
+ if (!tagp)
+ return FDT_END; /* premature end */
+ tag = fdt32_to_cpu (*tagp);
+ offset += FDT_TAGSIZE;
+
+ *nextoffset = -FDT_ERR_BADSTRUCTURE;
+ switch (tag)
+ {
+ case FDT_BEGIN_NODE:
+ /* skip name */
+ do
+ {
+ p = fdt_offset_ptr (fdt, offset++, 1);
}
-
- if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
- return FDT_END; /* premature end */
-
- *nextoffset = FDT_TAGALIGN(offset);
- return tag;
+ while (p && (*p != '\0'));
+ if (!p)
+ return FDT_END; /* premature end */
+ break;
+
+ case FDT_PROP:
+ lenp = fdt_offset_ptr (fdt, offset, sizeof (*lenp));
+ if (!lenp)
+ return FDT_END; /* premature end */
+ /* skip-name offset, length and value */
+ offset += sizeof (struct fdt_property) - FDT_TAGSIZE
+ + fdt32_to_cpu (*lenp);
+ break;
+
+ case FDT_END:
+ case FDT_END_NODE:
+ case FDT_NOP:
+ break;
+
+ default:
+ return FDT_END;
+ }
+
+ if (!fdt_offset_ptr (fdt, startoffset, offset - startoffset))
+ return FDT_END; /* premature end */
+
+ *nextoffset = FDT_TAGALIGN (offset);
+ return tag;
}
-int _fdt_check_node_offset(const void *fdt, int offset)
+int
+_fdt_check_node_offset (const void *fdt, int offset)
{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
- return -FDT_ERR_BADOFFSET;
+ if ((offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag (fdt, offset, &offset) != FDT_BEGIN_NODE))
+ return -FDT_ERR_BADOFFSET;
- return offset;
+ return offset;
}
-int _fdt_check_prop_offset(const void *fdt, int offset)
+int
+_fdt_check_prop_offset (const void *fdt, int offset)
{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
- return -FDT_ERR_BADOFFSET;
+ if ((offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag (fdt, offset, &offset) != FDT_PROP))
+ return -FDT_ERR_BADOFFSET;
- return offset;
+ return offset;
}
-int fdt_next_node(const void *fdt, int offset, int *depth)
+int
+fdt_next_node (const void *fdt, int offset, int *depth)
{
- int nextoffset = 0;
- uint32_t tag;
-
- if (offset >= 0)
- if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
- return nextoffset;
-
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_PROP:
- case FDT_NOP:
- break;
-
- case FDT_BEGIN_NODE:
- if (depth)
- (*depth)++;
- break;
-
- case FDT_END_NODE:
- if (depth && ((--(*depth)) < 0))
- return nextoffset;
- break;
-
- case FDT_END:
- if ((nextoffset >= 0)
- || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
- return -FDT_ERR_NOTFOUND;
- else
- return nextoffset;
- }
- } while (tag != FDT_BEGIN_NODE);
-
- return offset;
+ int nextoffset = 0;
+ uint32_t tag;
+
+ if (offset >= 0)
+ if ((nextoffset = _fdt_check_node_offset (fdt, offset)) < 0)
+ return nextoffset;
+
+ do
+ {
+ offset = nextoffset;
+ tag = fdt_next_tag (fdt, offset, &nextoffset);
+
+ switch (tag)
+ {
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ case FDT_BEGIN_NODE:
+ if (depth)
+ (*depth)++;
+ break;
+
+ case FDT_END_NODE:
+ if (depth && ((--(*depth)) < 0))
+ return nextoffset;
+ break;
+
+ case FDT_END:
+ if ((nextoffset >= 0)
+ || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
+ return -FDT_ERR_NOTFOUND;
+ else
+ return nextoffset;
+ }
+ }
+ while (tag != FDT_BEGIN_NODE);
+
+ return offset;
}
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
+const char *
+_fdt_find_string (const char *strtab, int tabsize, const char *s)
{
- int len = strlen(s) + 1;
- const char *last = strtab + tabsize - len;
- const char *p;
-
- for (p = strtab; p <= last; p++)
- if (memcmp(p, s, len) == 0)
- return p;
- return NULL;
+ int len = strlen (s) + 1;
+ const char *last = strtab + tabsize - len;
+ const char *p;
+
+ for (p = strtab; p <= last; p++)
+ if (memcmp (p, s, len) == 0)
+ return p;
+ return NULL;
}
-int fdt_move(const void *fdt, void *buf, int bufsize)
+int
+fdt_move (const void *fdt, void *buf, int bufsize)
{
- FDT_CHECK_HEADER(fdt);
+ FDT_CHECK_HEADER (fdt);
- if (fdt_totalsize(fdt) > bufsize)
- return -FDT_ERR_NOSPACE;
+ if (fdt_totalsize (fdt) > bufsize)
+ return -FDT_ERR_NOSPACE;
- memmove(buf, fdt, fdt_totalsize(fdt));
- return 0;
+ memmove (buf, fdt, fdt_totalsize (fdt));
+ return 0;
}
diff --git a/grub-core/lib/dtc/libfdt/fdt.h b/grub-core/lib/dtc/libfdt/fdt.h
index 48ccfd9..25bd308 100644
--- a/grub-core/lib/dtc/libfdt/fdt.h
+++ b/grub-core/lib/dtc/libfdt/fdt.h
@@ -3,40 +3,44 @@
#ifndef __ASSEMBLY__
-struct fdt_header {
- uint32_t magic; /* magic word FDT_MAGIC */
- uint32_t totalsize; /* total size of DT block */
- uint32_t off_dt_struct; /* offset to structure */
- uint32_t off_dt_strings; /* offset to strings */
- uint32_t off_mem_rsvmap; /* offset to memory reserve map */
- uint32_t version; /* format version */
- uint32_t last_comp_version; /* last compatible version */
-
- /* version 2 fields below */
- uint32_t boot_cpuid_phys; /* Which physical CPU id we're
- booting on */
- /* version 3 fields below */
- uint32_t size_dt_strings; /* size of the strings block */
-
- /* version 17 fields below */
- uint32_t size_dt_struct; /* size of the structure block */
+struct fdt_header
+{
+ uint32_t magic; /* magic word FDT_MAGIC */
+ uint32_t totalsize; /* total size of DT block */
+ uint32_t off_dt_struct; /* offset to structure */
+ uint32_t off_dt_strings; /* offset to strings */
+ uint32_t off_mem_rsvmap; /* offset to memory reserve map */
+ uint32_t version; /* format version */
+ uint32_t last_comp_version; /* last compatible version */
+
+ /* version 2 fields below */
+ uint32_t boot_cpuid_phys; /* Which physical CPU id we're
+ booting on */
+ /* version 3 fields below */
+ uint32_t size_dt_strings; /* size of the strings block */
+
+ /* version 17 fields below */
+ uint32_t size_dt_struct; /* size of the structure block */
};
-struct fdt_reserve_entry {
- uint64_t address;
- uint64_t size;
+struct fdt_reserve_entry
+{
+ uint64_t address;
+ uint64_t size;
};
-struct fdt_node_header {
- uint32_t tag;
- char name[0];
+struct fdt_node_header
+{
+ uint32_t tag;
+ char name[0];
};
-struct fdt_property {
- uint32_t tag;
- uint32_t len;
- uint32_t nameoff;
- char data[0];
+struct fdt_property
+{
+ uint32_t tag;
+ uint32_t len;
+ uint32_t nameoff;
+ char data[0];
};
#endif /* !__ASSEMBLY */
@@ -44,11 +48,11 @@ struct fdt_property {
#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
#define FDT_TAGSIZE sizeof(uint32_t)
-#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
-#define FDT_END_NODE 0x2 /* End node */
-#define FDT_PROP 0x3 /* Property: name off,
- size, content */
-#define FDT_NOP 0x4 /* nop */
+#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
+#define FDT_END_NODE 0x2 /* End node */
+#define FDT_PROP 0x3 /* Property: name off,
+ size, content */
+#define FDT_NOP 0x4 /* nop */
#define FDT_END 0x9
#define FDT_V1_SIZE (7*sizeof(uint32_t))
diff --git a/grub-core/lib/dtc/libfdt/fdt_ro.c b/grub-core/lib/dtc/libfdt/fdt_ro.c
index 02b6d68..7014e30 100644
--- a/grub-core/lib/dtc/libfdt/fdt_ro.c
+++ b/grub-core/lib/dtc/libfdt/fdt_ro.c
@@ -55,520 +55,554 @@
#include "libfdt_internal.h"
-static int _fdt_nodename_eq(const void *fdt, int offset,
- const char *s, int len)
+static int
+_fdt_nodename_eq (const void *fdt, int offset, const char *s, int len)
{
- const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
+ const char *p = fdt_offset_ptr (fdt, offset + FDT_TAGSIZE, len + 1);
- if (! p)
- /* short match */
- return 0;
+ if (!p)
+ /* short match */
+ return 0;
- if (memcmp(p, s, len) != 0)
- return 0;
+ if (memcmp (p, s, len) != 0)
+ return 0;
- if (p[len] == '\0')
- return 1;
- else if (!memchr(s, '@', len) && (p[len] == '@'))
- return 1;
- else
- return 0;
+ if (p[len] == '\0')
+ return 1;
+ else if (!memchr (s, '@', len) && (p[len] == '@'))
+ return 1;
+ else
+ return 0;
}
-const char *fdt_string(const void *fdt, int stroffset)
+const char *
+fdt_string (const void *fdt, int stroffset)
{
- return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
+ return (const char *) fdt + fdt_off_dt_strings (fdt) + stroffset;
}
-static int _fdt_string_eq(const void *fdt, int stroffset,
- const char *s, int len)
+static int
+_fdt_string_eq (const void *fdt, int stroffset, const char *s, int len)
{
- const char *p = fdt_string(fdt, stroffset);
+ const char *p = fdt_string (fdt, stroffset);
- return (strlen(p) == len) && (memcmp(p, s, len) == 0);
+ return (strlen (p) == len) && (memcmp (p, s, len) == 0);
}
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
+int
+fdt_get_mem_rsv (const void *fdt, int n, uint64_t * address, uint64_t * size)
{
- FDT_CHECK_HEADER(fdt);
- *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
- *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
- return 0;
+ FDT_CHECK_HEADER (fdt);
+ *address = fdt64_to_cpu (_fdt_mem_rsv (fdt, n)->address);
+ *size = fdt64_to_cpu (_fdt_mem_rsv (fdt, n)->size);
+ return 0;
}
-int fdt_num_mem_rsv(const void *fdt)
+int
+fdt_num_mem_rsv (const void *fdt)
{
- int i = 0;
+ int i = 0;
- while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
- i++;
- return i;
+ while (fdt64_to_cpu (_fdt_mem_rsv (fdt, i)->size) != 0)
+ i++;
+ return i;
}
-static int _nextprop(const void *fdt, int offset)
+static int
+_nextprop (const void *fdt, int offset)
{
- uint32_t tag;
- int nextoffset;
-
- do {
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_END:
- if (nextoffset >= 0)
- return -FDT_ERR_BADSTRUCTURE;
- else
- return nextoffset;
-
- case FDT_PROP:
- return offset;
- }
- offset = nextoffset;
- } while (tag == FDT_NOP);
-
- return -FDT_ERR_NOTFOUND;
+ uint32_t tag;
+ int nextoffset;
+
+ do
+ {
+ tag = fdt_next_tag (fdt, offset, &nextoffset);
+
+ switch (tag)
+ {
+ case FDT_END:
+ if (nextoffset >= 0)
+ return -FDT_ERR_BADSTRUCTURE;
+ else
+ return nextoffset;
+
+ case FDT_PROP:
+ return offset;
+ }
+ offset = nextoffset;
+ }
+ while (tag == FDT_NOP);
+
+ return -FDT_ERR_NOTFOUND;
}
-int fdt_subnode_offset_namelen(const void *fdt, int offset,
- const char *name, int namelen)
+int
+fdt_subnode_offset_namelen (const void *fdt, int offset,
+ const char *name, int namelen)
{
- int depth;
+ int depth;
- FDT_CHECK_HEADER(fdt);
+ FDT_CHECK_HEADER (fdt);
- for (depth = 0;
- (offset >= 0) && (depth >= 0);
- offset = fdt_next_node(fdt, offset, &depth))
- if ((depth == 1)
- && _fdt_nodename_eq(fdt, offset, name, namelen))
- return offset;
+ for (depth = 0;
+ (offset >= 0) && (depth >= 0);
+ offset = fdt_next_node (fdt, offset, &depth))
+ if ((depth == 1) && _fdt_nodename_eq (fdt, offset, name, namelen))
+ return offset;
- if (depth < 0)
- return -FDT_ERR_NOTFOUND;
- return offset; /* error */
+ if (depth < 0)
+ return -FDT_ERR_NOTFOUND;
+ return offset; /* error */
}
-int fdt_subnode_offset(const void *fdt, int parentoffset,
- const char *name)
+int
+fdt_subnode_offset (const void *fdt, int parentoffset, const char *name)
{
- return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
+ return fdt_subnode_offset_namelen (fdt, parentoffset, name, strlen (name));
}
-int fdt_path_offset(const void *fdt, const char *path)
+int
+fdt_path_offset (const void *fdt, const char *path)
{
- const char *end = path + strlen(path);
- const char *p = path;
- int offset = 0;
+ const char *end = path + strlen (path);
+ const char *p = path;
+ int offset = 0;
- FDT_CHECK_HEADER(fdt);
+ FDT_CHECK_HEADER (fdt);
- /* see if we have an alias */
- if (*path != '/') {
- const char *q = strchr(path, '/');
+ /* see if we have an alias */
+ if (*path != '/')
+ {
+ const char *q = strchr (path, '/');
- if (!q)
- q = end;
+ if (!q)
+ q = end;
- p = fdt_get_alias_namelen(fdt, p, q - p);
- if (!p)
- return -FDT_ERR_BADPATH;
- offset = fdt_path_offset(fdt, p);
+ p = fdt_get_alias_namelen (fdt, p, q - p);
+ if (!p)
+ return -FDT_ERR_BADPATH;
+ offset = fdt_path_offset (fdt, p);
- p = q;
- }
+ p = q;
+ }
- while (*p) {
- const char *q;
+ while (*p)
+ {
+ const char *q;
- while (*p == '/')
- p++;
- if (! *p)
- return offset;
- q = strchr(p, '/');
- if (! q)
- q = end;
+ while (*p == '/')
+ p++;
+ if (!*p)
+ return offset;
+ q = strchr (p, '/');
+ if (!q)
+ q = end;
- offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
- if (offset < 0)
- return offset;
+ offset = fdt_subnode_offset_namelen (fdt, offset, p, q - p);
+ if (offset < 0)
+ return offset;
- p = q;
- }
+ p = q;
+ }
- return offset;
+ return offset;
}
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
+const char *
+fdt_get_name (const void *fdt, int nodeoffset, int *len)
{
- const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
- int err;
+ const struct fdt_node_header *nh = _fdt_offset_ptr (fdt, nodeoffset);
+ int err;
- if (((err = fdt_check_header(fdt)) != 0)
- || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
- goto fail;
+ if (((err = fdt_check_header (fdt)) != 0)
+ || ((err = _fdt_check_node_offset (fdt, nodeoffset)) < 0))
+ goto fail;
- if (len)
- *len = strlen(nh->name);
+ if (len)
+ *len = strlen (nh->name);
- return nh->name;
+ return nh->name;
- fail:
- if (len)
- *len = err;
- return NULL;
+fail:
+ if (len)
+ *len = err;
+ return NULL;
}
-int fdt_first_property_offset(const void *fdt, int nodeoffset)
+int
+fdt_first_property_offset (const void *fdt, int nodeoffset)
{
- int offset;
+ int offset;
- if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
- return offset;
+ if ((offset = _fdt_check_node_offset (fdt, nodeoffset)) < 0)
+ return offset;
- return _nextprop(fdt, offset);
+ return _nextprop (fdt, offset);
}
-int fdt_next_property_offset(const void *fdt, int offset)
+int
+fdt_next_property_offset (const void *fdt, int offset)
{
- if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
- return offset;
+ if ((offset = _fdt_check_prop_offset (fdt, offset)) < 0)
+ return offset;
- return _nextprop(fdt, offset);
+ return _nextprop (fdt, offset);
}
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
- int offset,
- int *lenp)
+const struct fdt_property *
+fdt_get_property_by_offset (const void *fdt, int offset, int *lenp)
{
- int err;
- const struct fdt_property *prop;
+ int err;
+ const struct fdt_property *prop;
- if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
- if (lenp)
- *lenp = err;
- return NULL;
- }
+ if ((err = _fdt_check_prop_offset (fdt, offset)) < 0)
+ {
+ if (lenp)
+ *lenp = err;
+ return NULL;
+ }
- prop = _fdt_offset_ptr(fdt, offset);
+ prop = _fdt_offset_ptr (fdt, offset);
- if (lenp)
- *lenp = fdt32_to_cpu(prop->len);
+ if (lenp)
+ *lenp = fdt32_to_cpu (prop->len);
- return prop;
+ return prop;
}
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
- int offset,
- const char *name,
- int namelen, int *lenp)
+const struct fdt_property *
+fdt_get_property_namelen (const void *fdt,
+ int offset,
+ const char *name, int namelen, int *lenp)
{
- for (offset = fdt_first_property_offset(fdt, offset);
- (offset >= 0);
- (offset = fdt_next_property_offset(fdt, offset))) {
- const struct fdt_property *prop;
-
- if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
- offset = -FDT_ERR_INTERNAL;
- break;
- }
- if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
- name, namelen))
- return prop;
+ for (offset = fdt_first_property_offset (fdt, offset);
+ (offset >= 0); (offset = fdt_next_property_offset (fdt, offset)))
+ {
+ const struct fdt_property *prop;
+
+ if (!(prop = fdt_get_property_by_offset (fdt, offset, lenp)))
+ {
+ offset = -FDT_ERR_INTERNAL;
+ break;
}
+ if (_fdt_string_eq (fdt, fdt32_to_cpu (prop->nameoff), name, namelen))
+ return prop;
+ }
- if (lenp)
- *lenp = offset;
- return NULL;
+ if (lenp)
+ *lenp = offset;
+ return NULL;
}
-const struct fdt_property *fdt_get_property(const void *fdt,
- int nodeoffset,
- const char *name, int *lenp)
+const struct fdt_property *
+fdt_get_property (const void *fdt,
+ int nodeoffset, const char *name, int *lenp)
{
- return fdt_get_property_namelen(fdt, nodeoffset, name,
- strlen(name), lenp);
+ return fdt_get_property_namelen (fdt, nodeoffset, name,
+ strlen (name), lenp);
}
-const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
- const char *name, int namelen, int *lenp)
+const void *
+fdt_getprop_namelen (const void *fdt, int nodeoffset,
+ const char *name, int namelen, int *lenp)
{
- const struct fdt_property *prop;
+ const struct fdt_property *prop;
- prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
- if (! prop)
- return NULL;
+ prop = fdt_get_property_namelen (fdt, nodeoffset, name, namelen, lenp);
+ if (!prop)
+ return NULL;
- return prop->data;
+ return prop->data;
}
-const void *fdt_getprop_by_offset(const void *fdt, int offset,
- const char **namep, int *lenp)
+const void *
+fdt_getprop_by_offset (const void *fdt, int offset,
+ const char **namep, int *lenp)
{
- const struct fdt_property *prop;
-
- prop = fdt_get_property_by_offset(fdt, offset, lenp);
- if (!prop)
- return NULL;
- if (namep)
- *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
- return prop->data;
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_by_offset (fdt, offset, lenp);
+ if (!prop)
+ return NULL;
+ if (namep)
+ *namep = fdt_string (fdt, fdt32_to_cpu (prop->nameoff));
+ return prop->data;
}
-const void *fdt_getprop(const void *fdt, int nodeoffset,
- const char *name, int *lenp)
+const void *
+fdt_getprop (const void *fdt, int nodeoffset, const char *name, int *lenp)
{
- return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
+ return fdt_getprop_namelen (fdt, nodeoffset, name, strlen (name), lenp);
}
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
+uint32_t
+fdt_get_phandle (const void *fdt, int nodeoffset)
{
- const uint32_t *php;
- int len;
-
- /* FIXME: This is a bit sub-optimal, since we potentially scan
- * over all the properties twice. */
- php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
- if (!php || (len != sizeof(*php))) {
- php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
- if (!php || (len != sizeof(*php)))
- return 0;
- }
+ const uint32_t *php;
+ int len;
+
+ /* FIXME: This is a bit sub-optimal, since we potentially scan
+ * over all the properties twice. */
+ php = fdt_getprop (fdt, nodeoffset, "phandle", &len);
+ if (!php || (len != sizeof (*php)))
+ {
+ php = fdt_getprop (fdt, nodeoffset, "linux,phandle", &len);
+ if (!php || (len != sizeof (*php)))
+ return 0;
+ }
- return fdt32_to_cpu(*php);
+ return fdt32_to_cpu (*php);
}
-const char *fdt_get_alias_namelen(const void *fdt,
- const char *name, int namelen)
+const char *
+fdt_get_alias_namelen (const void *fdt, const char *name, int namelen)
{
- int aliasoffset;
+ int aliasoffset;
- aliasoffset = fdt_path_offset(fdt, "/aliases");
- if (aliasoffset < 0)
- return NULL;
+ aliasoffset = fdt_path_offset (fdt, "/aliases");
+ if (aliasoffset < 0)
+ return NULL;
- return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
+ return fdt_getprop_namelen (fdt, aliasoffset, name, namelen, NULL);
}
-const char *fdt_get_alias(const void *fdt, const char *name)
+const char *
+fdt_get_alias (const void *fdt, const char *name)
{
- return fdt_get_alias_namelen(fdt, name, strlen(name));
+ return fdt_get_alias_namelen (fdt, name, strlen (name));
}
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
+int
+fdt_get_path (const void *fdt, int nodeoffset, char *buf, int buflen)
{
- int pdepth = 0, p = 0;
- int offset, depth, namelen;
- const char *name;
-
- FDT_CHECK_HEADER(fdt);
-
- if (buflen < 2)
- return -FDT_ERR_NOSPACE;
-
- for (offset = 0, depth = 0;
- (offset >= 0) && (offset <= nodeoffset);
- offset = fdt_next_node(fdt, offset, &depth)) {
- while (pdepth > depth) {
- do {
- p--;
- } while (buf[p-1] != '/');
- pdepth--;
- }
-
- if (pdepth >= depth) {
- name = fdt_get_name(fdt, offset, &namelen);
- if (!name)
- return namelen;
- if ((p + namelen + 1) <= buflen) {
- memcpy(buf + p, name, namelen);
- p += namelen;
- buf[p++] = '/';
- pdepth++;
- }
- }
-
- if (offset == nodeoffset) {
- if (pdepth < (depth + 1))
- return -FDT_ERR_NOSPACE;
-
- if (p > 1) /* special case so that root path is "/", not "" */
- p--;
- buf[p] = '\0';
- return 0;
- }
+ int pdepth = 0, p = 0;
+ int offset, depth, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER (fdt);
+
+ if (buflen < 2)
+ return -FDT_ERR_NOSPACE;
+
+ for (offset = 0, depth = 0;
+ (offset >= 0) && (offset <= nodeoffset);
+ offset = fdt_next_node (fdt, offset, &depth))
+ {
+ while (pdepth > depth)
+ {
+ do
+ {
+ p--;
+ }
+ while (buf[p - 1] != '/');
+ pdepth--;
}
- if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
- return -FDT_ERR_BADOFFSET;
- else if (offset == -FDT_ERR_BADOFFSET)
- return -FDT_ERR_BADSTRUCTURE;
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
- int supernodedepth, int *nodedepth)
-{
- int offset, depth;
- int supernodeoffset = -FDT_ERR_INTERNAL;
+ if (pdepth >= depth)
+ {
+ name = fdt_get_name (fdt, offset, &namelen);
+ if (!name)
+ return namelen;
+ if ((p + namelen + 1) <= buflen)
+ {
+ memcpy (buf + p, name, namelen);
+ p += namelen;
+ buf[p++] = '/';
+ pdepth++;
+ }
+ }
- FDT_CHECK_HEADER(fdt);
+ if (offset == nodeoffset)
+ {
+ if (pdepth < (depth + 1))
+ return -FDT_ERR_NOSPACE;
- if (supernodedepth < 0)
- return -FDT_ERR_NOTFOUND;
+ if (p > 1) /* special case so that root path is "/", not "" */
+ p--;
+ buf[p] = '\0';
+ return 0;
+ }
+ }
- for (offset = 0, depth = 0;
- (offset >= 0) && (offset <= nodeoffset);
- offset = fdt_next_node(fdt, offset, &depth)) {
- if (depth == supernodedepth)
- supernodeoffset = offset;
+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
+ return -FDT_ERR_BADOFFSET;
+ else if (offset == -FDT_ERR_BADOFFSET)
+ return -FDT_ERR_BADSTRUCTURE;
- if (offset == nodeoffset) {
- if (nodedepth)
- *nodedepth = depth;
+ return offset; /* error from fdt_next_node() */
+}
- if (supernodedepth > depth)
- return -FDT_ERR_NOTFOUND;
- else
- return supernodeoffset;
- }
+int
+fdt_supernode_atdepth_offset (const void *fdt, int nodeoffset,
+ int supernodedepth, int *nodedepth)
+{
+ int offset, depth;
+ int supernodeoffset = -FDT_ERR_INTERNAL;
+
+ FDT_CHECK_HEADER (fdt);
+
+ if (supernodedepth < 0)
+ return -FDT_ERR_NOTFOUND;
+
+ for (offset = 0, depth = 0;
+ (offset >= 0) && (offset <= nodeoffset);
+ offset = fdt_next_node (fdt, offset, &depth))
+ {
+ if (depth == supernodedepth)
+ supernodeoffset = offset;
+
+ if (offset == nodeoffset)
+ {
+ if (nodedepth)
+ *nodedepth = depth;
+
+ if (supernodedepth > depth)
+ return -FDT_ERR_NOTFOUND;
+ else
+ return supernodeoffset;
}
+ }
- if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
- return -FDT_ERR_BADOFFSET;
- else if (offset == -FDT_ERR_BADOFFSET)
- return -FDT_ERR_BADSTRUCTURE;
+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
+ return -FDT_ERR_BADOFFSET;
+ else if (offset == -FDT_ERR_BADOFFSET)
+ return -FDT_ERR_BADSTRUCTURE;
- return offset; /* error from fdt_next_node() */
+ return offset; /* error from fdt_next_node() */
}
-int fdt_node_depth(const void *fdt, int nodeoffset)
+int
+fdt_node_depth (const void *fdt, int nodeoffset)
{
- int nodedepth;
- int err;
+ int nodedepth;
+ int err;
- err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
- if (err)
- return (err < 0) ? err : -FDT_ERR_INTERNAL;
- return nodedepth;
+ err = fdt_supernode_atdepth_offset (fdt, nodeoffset, 0, &nodedepth);
+ if (err)
+ return (err < 0) ? err : -FDT_ERR_INTERNAL;
+ return nodedepth;
}
-int fdt_parent_offset(const void *fdt, int nodeoffset)
+int
+fdt_parent_offset (const void *fdt, int nodeoffset)
{
- int nodedepth = fdt_node_depth(fdt, nodeoffset);
+ int nodedepth = fdt_node_depth (fdt, nodeoffset);
- if (nodedepth < 0)
- return nodedepth;
- return fdt_supernode_atdepth_offset(fdt, nodeoffset,
- nodedepth - 1, NULL);
+ if (nodedepth < 0)
+ return nodedepth;
+ return fdt_supernode_atdepth_offset (fdt, nodeoffset, nodedepth - 1, NULL);
}
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
- const char *propname,
- const void *propval, int proplen)
+int
+fdt_node_offset_by_prop_value (const void *fdt, int startoffset,
+ const char *propname,
+ const void *propval, int proplen)
{
- int offset;
- const void *val;
- int len;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we scan each
- * property of a node in fdt_getprop(), then if that didn't
- * find what we want, we scan over them again making our way
- * to the next node. Still it's the easiest to implement
- * approach; performance can come later. */
- for (offset = fdt_next_node(fdt, startoffset, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- val = fdt_getprop(fdt, offset, propname, &len);
- if (val && (len == proplen)
- && (memcmp(val, propval, len) == 0))
- return offset;
- }
+ int offset;
+ const void *val;
+ int len;
+
+ FDT_CHECK_HEADER (fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_getprop(), then if that didn't
+ * find what we want, we scan over them again making our way
+ * to the next node. Still it's the easiest to implement
+ * approach; performance can come later. */
+ for (offset = fdt_next_node (fdt, startoffset, NULL);
+ offset >= 0; offset = fdt_next_node (fdt, offset, NULL))
+ {
+ val = fdt_getprop (fdt, offset, propname, &len);
+ if (val && (len == proplen) && (memcmp (val, propval, len) == 0))
+ return offset;
+ }
- return offset; /* error from fdt_next_node() */
+ return offset; /* error from fdt_next_node() */
}
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
+int
+fdt_node_offset_by_phandle (const void *fdt, uint32_t phandle)
{
- int offset;
-
- if ((phandle == 0) || (phandle == -1))
- return -FDT_ERR_BADPHANDLE;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we
- * potentially scan each property of a node in
- * fdt_get_phandle(), then if that didn't find what
- * we want, we scan over them again making our way to the next
- * node. Still it's the easiest to implement approach;
- * performance can come later. */
- for (offset = fdt_next_node(fdt, -1, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- if (fdt_get_phandle(fdt, offset) == phandle)
- return offset;
- }
+ int offset;
+
+ if ((phandle == 0) || (phandle == -1))
+ return -FDT_ERR_BADPHANDLE;
+
+ FDT_CHECK_HEADER (fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we
+ * potentially scan each property of a node in
+ * fdt_get_phandle(), then if that didn't find what
+ * we want, we scan over them again making our way to the next
+ * node. Still it's the easiest to implement approach;
+ * performance can come later. */
+ for (offset = fdt_next_node (fdt, -1, NULL);
+ offset >= 0; offset = fdt_next_node (fdt, offset, NULL))
+ {
+ if (fdt_get_phandle (fdt, offset) == phandle)
+ return offset;
+ }
- return offset; /* error from fdt_next_node() */
+ return offset; /* error from fdt_next_node() */
}
-static int _fdt_stringlist_contains(const char *strlist, int listlen,
- const char *str)
+static int
+_fdt_stringlist_contains (const char *strlist, int listlen, const char *str)
{
- int len = strlen(str);
- const char *p;
-
- while (listlen >= len) {
- if (memcmp(str, strlist, len+1) == 0)
- return 1;
- p = memchr(strlist, '\0', listlen);
- if (!p)
- return 0; /* malformed strlist.. */
- listlen -= (p-strlist) + 1;
- strlist = p + 1;
- }
- return 0;
+ int len = strlen (str);
+ const char *p;
+
+ while (listlen >= len)
+ {
+ if (memcmp (str, strlist, len + 1) == 0)
+ return 1;
+ p = memchr (strlist, '\0', listlen);
+ if (!p)
+ return 0; /* malformed strlist.. */
+ listlen -= (p - strlist) + 1;
+ strlist = p + 1;
+ }
+ return 0;
}
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
- const char *compatible)
+int
+fdt_node_check_compatible (const void *fdt, int nodeoffset,
+ const char *compatible)
{
- const void *prop;
- int len;
-
- prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
- if (!prop)
- return len;
- if (_fdt_stringlist_contains(prop, len, compatible))
- return 0;
- else
- return 1;
+ const void *prop;
+ int len;
+
+ prop = fdt_getprop (fdt, nodeoffset, "compatible", &len);
+ if (!prop)
+ return len;
+ if (_fdt_stringlist_contains (prop, len, compatible))
+ return 0;
+ else
+ return 1;
}
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
- const char *compatible)
+int
+fdt_node_offset_by_compatible (const void *fdt, int startoffset,
+ const char *compatible)
{
- int offset, err;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we scan each
- * property of a node in fdt_node_check_compatible(), then if
- * that didn't find what we want, we scan over them again
- * making our way to the next node. Still it's the easiest to
- * implement approach; performance can come later. */
- for (offset = fdt_next_node(fdt, startoffset, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- err = fdt_node_check_compatible(fdt, offset, compatible);
- if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
- return err;
- else if (err == 0)
- return offset;
- }
+ int offset, err;
+
+ FDT_CHECK_HEADER (fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_node_check_compatible(), then if
+ * that didn't find what we want, we scan over them again
+ * making our way to the next node. Still it's the easiest to
+ * implement approach; performance can come later. */
+ for (offset = fdt_next_node (fdt, startoffset, NULL);
+ offset >= 0; offset = fdt_next_node (fdt, offset, NULL))
+ {
+ err = fdt_node_check_compatible (fdt, offset, compatible);
+ if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
+ return err;
+ else if (err == 0)
+ return offset;
+ }
- return offset; /* error from fdt_next_node() */
+ return offset; /* error from fdt_next_node() */
}
diff --git a/grub-core/lib/dtc/libfdt/fdt_rw.c b/grub-core/lib/dtc/libfdt/fdt_rw.c
index 994037b..58bc4ad 100644
--- a/grub-core/lib/dtc/libfdt/fdt_rw.c
+++ b/grub-core/lib/dtc/libfdt/fdt_rw.c
@@ -55,31 +55,31 @@
#include "libfdt_internal.h"
-static int _fdt_blocks_misordered(const void *fdt,
- int mem_rsv_size, int struct_size)
+static int
+_fdt_blocks_misordered (const void *fdt, int mem_rsv_size, int struct_size)
{
- return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
- || (fdt_off_dt_struct(fdt) <
- (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
- || (fdt_off_dt_strings(fdt) <
- (fdt_off_dt_struct(fdt) + struct_size))
- || (fdt_totalsize(fdt) <
- (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
+ return (fdt_off_mem_rsvmap (fdt) <
+ FDT_ALIGN (sizeof (struct fdt_header), 8))
+ || (fdt_off_dt_struct (fdt) < (fdt_off_mem_rsvmap (fdt) + mem_rsv_size))
+ || (fdt_off_dt_strings (fdt) < (fdt_off_dt_struct (fdt) + struct_size))
+ || (fdt_totalsize (fdt) <
+ (fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt)));
}
-static int _fdt_rw_check_header(void *fdt)
+static int
+_fdt_rw_check_header (void *fdt)
{
- FDT_CHECK_HEADER(fdt);
+ FDT_CHECK_HEADER (fdt);
- if (fdt_version(fdt) < 17)
- return -FDT_ERR_BADVERSION;
- if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
- fdt_size_dt_struct(fdt)))
- return -FDT_ERR_BADLAYOUT;
- if (fdt_version(fdt) > 17)
- fdt_set_version(fdt, 17);
+ if (fdt_version (fdt) < 17)
+ return -FDT_ERR_BADVERSION;
+ if (_fdt_blocks_misordered (fdt, sizeof (struct fdt_reserve_entry),
+ fdt_size_dt_struct (fdt)))
+ return -FDT_ERR_BADLAYOUT;
+ if (fdt_version (fdt) > 17)
+ fdt_set_version (fdt, 17);
- return 0;
+ return 0;
}
#define FDT_RW_CHECK_HEADER(fdt) \
@@ -89,377 +89,402 @@ static int _fdt_rw_check_header(void *fdt)
return err; \
}
-static inline int _fdt_data_size(void *fdt)
+static inline int
+_fdt_data_size (void *fdt)
{
- return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+ return fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt);
}
-static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
+static int
+_fdt_splice (void *fdt, void *splicepoint, int oldlen, int newlen)
{
- char *p = splicepoint;
- char *end = (char *)fdt + _fdt_data_size(fdt);
-
- if (((p + oldlen) < p) || ((p + oldlen) > end))
- return -FDT_ERR_BADOFFSET;
- if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
- return -FDT_ERR_NOSPACE;
- memmove(p + newlen, p + oldlen, end - p - oldlen);
- return 0;
+ char *p = splicepoint;
+ char *end = (char *) fdt + _fdt_data_size (fdt);
+
+ if (((p + oldlen) < p) || ((p + oldlen) > end))
+ return -FDT_ERR_BADOFFSET;
+ if ((end - oldlen + newlen) > ((char *) fdt + fdt_totalsize (fdt)))
+ return -FDT_ERR_NOSPACE;
+ memmove (p + newlen, p + oldlen, end - p - oldlen);
+ return 0;
}
-static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
- int oldn, int newn)
+static int
+_fdt_splice_mem_rsv (void *fdt, struct fdt_reserve_entry *p,
+ int oldn, int newn)
{
- int delta = (newn - oldn) * sizeof(*p);
- int err;
- err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
- if (err)
- return err;
- fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
- fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
- return 0;
+ int delta = (newn - oldn) * sizeof (*p);
+ int err;
+ err = _fdt_splice (fdt, p, oldn * sizeof (*p), newn * sizeof (*p));
+ if (err)
+ return err;
+ fdt_set_off_dt_struct (fdt, fdt_off_dt_struct (fdt) + delta);
+ fdt_set_off_dt_strings (fdt, fdt_off_dt_strings (fdt) + delta);
+ return 0;
}
-static int _fdt_splice_struct(void *fdt, void *p,
- int oldlen, int newlen)
+static int
+_fdt_splice_struct (void *fdt, void *p, int oldlen, int newlen)
{
- int delta = newlen - oldlen;
- int err;
+ int delta = newlen - oldlen;
+ int err;
- if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
- return err;
+ if ((err = _fdt_splice (fdt, p, oldlen, newlen)))
+ return err;
- fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
- fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
- return 0;
+ fdt_set_size_dt_struct (fdt, fdt_size_dt_struct (fdt) + delta);
+ fdt_set_off_dt_strings (fdt, fdt_off_dt_strings (fdt) + delta);
+ return 0;
}
-static int _fdt_splice_string(void *fdt, int newlen)
+static int
+_fdt_splice_string (void *fdt, int newlen)
{
- void *p = (char *)fdt
- + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
- int err;
+ void *p = (char *) fdt
+ + fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt);
+ int err;
- if ((err = _fdt_splice(fdt, p, 0, newlen)))
- return err;
+ if ((err = _fdt_splice (fdt, p, 0, newlen)))
+ return err;
- fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
- return 0;
+ fdt_set_size_dt_strings (fdt, fdt_size_dt_strings (fdt) + newlen);
+ return 0;
}
-static int _fdt_find_add_string(void *fdt, const char *s)
+static int
+_fdt_find_add_string (void *fdt, const char *s)
{
- char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
- const char *p;
- char *new;
- int len = strlen(s) + 1;
- int err;
-
- p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
- if (p)
- /* found it */
- return (p - strtab);
-
- new = strtab + fdt_size_dt_strings(fdt);
- err = _fdt_splice_string(fdt, len);
- if (err)
- return err;
-
- memcpy(new, s, len);
- return (new - strtab);
+ char *strtab = (char *) fdt + fdt_off_dt_strings (fdt);
+ const char *p;
+ char *new;
+ int len = strlen (s) + 1;
+ int err;
+
+ p = _fdt_find_string (strtab, fdt_size_dt_strings (fdt), s);
+ if (p)
+ /* found it */
+ return (p - strtab);
+
+ new = strtab + fdt_size_dt_strings (fdt);
+ err = _fdt_splice_string (fdt, len);
+ if (err)
+ return err;
+
+ memcpy (new, s, len);
+ return (new - strtab);
}
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
+int
+fdt_add_mem_rsv (void *fdt, uint64_t address, uint64_t size)
{
- struct fdt_reserve_entry *re;
- int err;
+ struct fdt_reserve_entry *re;
+ int err;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
- err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
- if (err)
- return err;
+ re = _fdt_mem_rsv_w (fdt, fdt_num_mem_rsv (fdt));
+ err = _fdt_splice_mem_rsv (fdt, re, 0, 1);
+ if (err)
+ return err;
- re->address = cpu_to_fdt64(address);
- re->size = cpu_to_fdt64(size);
- return 0;
+ re->address = cpu_to_fdt64 (address);
+ re->size = cpu_to_fdt64 (size);
+ return 0;
}
-int fdt_del_mem_rsv(void *fdt, int n)
+int
+fdt_del_mem_rsv (void *fdt, int n)
{
- struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
- int err;
+ struct fdt_reserve_entry *re = _fdt_mem_rsv_w (fdt, n);
+ int err;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- if (n >= fdt_num_mem_rsv(fdt))
- return -FDT_ERR_NOTFOUND;
+ if (n >= fdt_num_mem_rsv (fdt))
+ return -FDT_ERR_NOTFOUND;
- err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
- if (err)
- return err;
- return 0;
+ err = _fdt_splice_mem_rsv (fdt, re, 1, 0);
+ if (err)
+ return err;
+ return 0;
}
-static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
+static int
+_fdt_resize_property (void *fdt, int nodeoffset, const char *name,
+ int len, struct fdt_property **prop)
{
- int oldlen;
- int err;
+ int oldlen;
+ int err;
- *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (! (*prop))
- return oldlen;
+ *prop = fdt_get_property_w (fdt, nodeoffset, name, &oldlen);
+ if (!(*prop))
+ return oldlen;
- if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
- FDT_TAGALIGN(len))))
- return err;
+ if ((err = _fdt_splice_struct (fdt, (*prop)->data, FDT_TAGALIGN (oldlen),
+ FDT_TAGALIGN (len))))
+ return err;
- (*prop)->len = cpu_to_fdt32(len);
- return 0;
+ (*prop)->len = cpu_to_fdt32 (len);
+ return 0;
}
-static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
+static int
+_fdt_add_property (void *fdt, int nodeoffset, const char *name,
+ int len, struct fdt_property **prop)
{
- int proplen;
- int nextoffset;
- int namestroff;
- int err;
+ int proplen;
+ int nextoffset;
+ int namestroff;
+ int err;
- if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
- return nextoffset;
+ if ((nextoffset = _fdt_check_node_offset (fdt, nodeoffset)) < 0)
+ return nextoffset;
- namestroff = _fdt_find_add_string(fdt, name);
- if (namestroff < 0)
- return namestroff;
+ namestroff = _fdt_find_add_string (fdt, name);
+ if (namestroff < 0)
+ return namestroff;
- *prop = _fdt_offset_ptr_w(fdt, nextoffset);
- proplen = sizeof(**prop) + FDT_TAGALIGN(len);
+ *prop = _fdt_offset_ptr_w (fdt, nextoffset);
+ proplen = sizeof (**prop) + FDT_TAGALIGN (len);
- err = _fdt_splice_struct(fdt, *prop, 0, proplen);
- if (err)
- return err;
+ err = _fdt_splice_struct (fdt, *prop, 0, proplen);
+ if (err)
+ return err;
- (*prop)->tag = cpu_to_fdt32(FDT_PROP);
- (*prop)->nameoff = cpu_to_fdt32(namestroff);
- (*prop)->len = cpu_to_fdt32(len);
- return 0;
+ (*prop)->tag = cpu_to_fdt32 (FDT_PROP);
+ (*prop)->nameoff = cpu_to_fdt32 (namestroff);
+ (*prop)->len = cpu_to_fdt32 (len);
+ return 0;
}
-int fdt_set_name(void *fdt, int nodeoffset, const char *name)
+int
+fdt_set_name (void *fdt, int nodeoffset, const char *name)
{
- char *namep;
- int oldlen, newlen;
- int err;
+ char *namep;
+ int oldlen, newlen;
+ int err;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
- if (!namep)
- return oldlen;
+ namep = (char *) (uintptr_t) fdt_get_name (fdt, nodeoffset, &oldlen);
+ if (!namep)
+ return oldlen;
- newlen = strlen(name);
+ newlen = strlen (name);
- err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
- FDT_TAGALIGN(newlen+1));
- if (err)
- return err;
+ err = _fdt_splice_struct (fdt, namep, FDT_TAGALIGN (oldlen + 1),
+ FDT_TAGALIGN (newlen + 1));
+ if (err)
+ return err;
- memcpy(namep, name, newlen+1);
- return 0;
+ memcpy (namep, name, newlen + 1);
+ return 0;
}
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int
+fdt_setprop (void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
{
- struct fdt_property *prop;
- int err;
+ struct fdt_property *prop;
+ int err;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
- if (err == -FDT_ERR_NOTFOUND)
- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
- if (err)
- return err;
+ err = _fdt_resize_property (fdt, nodeoffset, name, len, &prop);
+ if (err == -FDT_ERR_NOTFOUND)
+ err = _fdt_add_property (fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
- memcpy(prop->data, val, len);
- return 0;
+ memcpy (prop->data, val, len);
+ return 0;
}
-int fdt_delprop(void *fdt, int nodeoffset, const char *name)
+int
+fdt_delprop (void *fdt, int nodeoffset, const char *name)
{
- struct fdt_property *prop;
- int len, proplen;
+ struct fdt_property *prop;
+ int len, proplen;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
- return len;
+ prop = fdt_get_property_w (fdt, nodeoffset, name, &len);
+ if (!prop)
+ return len;
- proplen = sizeof(*prop) + FDT_TAGALIGN(len);
- return _fdt_splice_struct(fdt, prop, proplen, 0);
+ proplen = sizeof (*prop) + FDT_TAGALIGN (len);
+ return _fdt_splice_struct (fdt, prop, proplen, 0);
}
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
- const char *name, int namelen)
+int
+fdt_add_subnode_namelen (void *fdt, int parentoffset,
+ const char *name, int namelen)
{
- struct fdt_node_header *nh;
- int offset, nextoffset;
- int nodelen;
- int err;
- uint32_t tag;
- uint32_t *endtag;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
- if (offset >= 0)
- return -FDT_ERR_EXISTS;
- else if (offset != -FDT_ERR_NOTFOUND)
- return offset;
-
- /* Try to place the new node after the parent's properties */
- fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
- } while ((tag == FDT_PROP) || (tag == FDT_NOP));
-
- nh = _fdt_offset_ptr_w(fdt, offset);
- nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
-
- err = _fdt_splice_struct(fdt, nh, 0, nodelen);
- if (err)
- return err;
-
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
- memcpy(nh->name, name, namelen);
- endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
- *endtag = cpu_to_fdt32(FDT_END_NODE);
-
- return offset;
+ struct fdt_node_header *nh;
+ int offset, nextoffset;
+ int nodelen;
+ int err;
+ uint32_t tag;
+ uint32_t *endtag;
+
+ FDT_RW_CHECK_HEADER (fdt);
+
+ offset = fdt_subnode_offset_namelen (fdt, parentoffset, name, namelen);
+ if (offset >= 0)
+ return -FDT_ERR_EXISTS;
+ else if (offset != -FDT_ERR_NOTFOUND)
+ return offset;
+
+ /* Try to place the new node after the parent's properties */
+ fdt_next_tag (fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
+ do
+ {
+ offset = nextoffset;
+ tag = fdt_next_tag (fdt, offset, &nextoffset);
+ }
+ while ((tag == FDT_PROP) || (tag == FDT_NOP));
+
+ nh = _fdt_offset_ptr_w (fdt, offset);
+ nodelen = sizeof (*nh) + FDT_TAGALIGN (namelen + 1) + FDT_TAGSIZE;
+
+ err = _fdt_splice_struct (fdt, nh, 0, nodelen);
+ if (err)
+ return err;
+
+ nh->tag = cpu_to_fdt32 (FDT_BEGIN_NODE);
+ memset (nh->name, 0, FDT_TAGALIGN (namelen + 1));
+ memcpy (nh->name, name, namelen);
+ endtag = (uint32_t *) ((char *) nh + nodelen - FDT_TAGSIZE);
+ *endtag = cpu_to_fdt32 (FDT_END_NODE);
+
+ return offset;
}
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
+int
+fdt_add_subnode (void *fdt, int parentoffset, const char *name)
{
- return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
+ return fdt_add_subnode_namelen (fdt, parentoffset, name, strlen (name));
}
-int fdt_del_node(void *fdt, int nodeoffset)
+int
+fdt_del_node (void *fdt, int nodeoffset)
{
- int endoffset;
+ int endoffset;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
+ endoffset = _fdt_node_end_offset (fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
- return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
- endoffset - nodeoffset, 0);
+ return _fdt_splice_struct (fdt, _fdt_offset_ptr_w (fdt, nodeoffset),
+ endoffset - nodeoffset, 0);
}
-static void _fdt_packblocks(const char *old, char *new,
- int mem_rsv_size, int struct_size)
+static void
+_fdt_packblocks (const char *old, char *new,
+ int mem_rsv_size, int struct_size)
{
- int mem_rsv_off, struct_off, strings_off;
+ int mem_rsv_off, struct_off, strings_off;
- mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
- struct_off = mem_rsv_off + mem_rsv_size;
- strings_off = struct_off + struct_size;
+ mem_rsv_off = FDT_ALIGN (sizeof (struct fdt_header), 8);
+ struct_off = mem_rsv_off + mem_rsv_size;
+ strings_off = struct_off + struct_size;
- memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
- fdt_set_off_mem_rsvmap(new, mem_rsv_off);
+ memmove (new + mem_rsv_off, old + fdt_off_mem_rsvmap (old), mem_rsv_size);
+ fdt_set_off_mem_rsvmap (new, mem_rsv_off);
- memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
- fdt_set_off_dt_struct(new, struct_off);
- fdt_set_size_dt_struct(new, struct_size);
+ memmove (new + struct_off, old + fdt_off_dt_struct (old), struct_size);
+ fdt_set_off_dt_struct (new, struct_off);
+ fdt_set_size_dt_struct (new, struct_size);
- memmove(new + strings_off, old + fdt_off_dt_strings(old),
- fdt_size_dt_strings(old));
- fdt_set_off_dt_strings(new, strings_off);
- fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
+ memmove (new + strings_off, old + fdt_off_dt_strings (old),
+ fdt_size_dt_strings (old));
+ fdt_set_off_dt_strings (new, strings_off);
+ fdt_set_size_dt_strings (new, fdt_size_dt_strings (old));
}
-int fdt_open_into(const void *fdt, void *buf, int bufsize)
+int
+fdt_open_into (const void *fdt, void *buf, int bufsize)
{
- int err;
- int mem_rsv_size, struct_size;
- int newsize;
- const char *fdtstart = fdt;
- const char *fdtend = fdtstart + fdt_totalsize(fdt);
- char *tmp;
-
- FDT_CHECK_HEADER(fdt);
-
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
-
- if (fdt_version(fdt) >= 17) {
- struct_size = fdt_size_dt_struct(fdt);
- } else {
- struct_size = 0;
- while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
- ;
- if (struct_size < 0)
- return struct_size;
- }
-
- if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
- /* no further work necessary */
- err = fdt_move(fdt, buf, bufsize);
- if (err)
- return err;
- fdt_set_version(buf, 17);
- fdt_set_size_dt_struct(buf, struct_size);
- fdt_set_totalsize(buf, bufsize);
- return 0;
- }
-
- /* Need to reorder */
- newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
- + struct_size + fdt_size_dt_strings(fdt);
-
- if (bufsize < newsize)
- return -FDT_ERR_NOSPACE;
-
- /* First attempt to build converted tree at beginning of buffer */
- tmp = buf;
- /* But if that overlaps with the old tree... */
- if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
- /* Try right after the old tree instead */
- tmp = (char *)(uintptr_t)fdtend;
- if ((tmp + newsize) > ((char *)buf + bufsize))
- return -FDT_ERR_NOSPACE;
- }
-
- _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
- memmove(buf, tmp, newsize);
-
- fdt_set_magic(buf, FDT_MAGIC);
- fdt_set_totalsize(buf, bufsize);
- fdt_set_version(buf, 17);
- fdt_set_last_comp_version(buf, 16);
- fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
-
- return 0;
+ int err;
+ int mem_rsv_size, struct_size;
+ int newsize;
+ const char *fdtstart = fdt;
+ const char *fdtend = fdtstart + fdt_totalsize (fdt);
+ char *tmp;
+
+ FDT_CHECK_HEADER (fdt);
+
+ mem_rsv_size = (fdt_num_mem_rsv (fdt) + 1)
+ * sizeof (struct fdt_reserve_entry);
+
+ if (fdt_version (fdt) >= 17)
+ {
+ struct_size = fdt_size_dt_struct (fdt);
+ }
+ else
+ {
+ struct_size = 0;
+ while (fdt_next_tag (fdt, struct_size, &struct_size) != FDT_END)
+ ;
+ if (struct_size < 0)
+ return struct_size;
+ }
+
+ if (!_fdt_blocks_misordered (fdt, mem_rsv_size, struct_size))
+ {
+ /* no further work necessary */
+ err = fdt_move (fdt, buf, bufsize);
+ if (err)
+ return err;
+ fdt_set_version (buf, 17);
+ fdt_set_size_dt_struct (buf, struct_size);
+ fdt_set_totalsize (buf, bufsize);
+ return 0;
+ }
+
+ /* Need to reorder */
+ newsize = FDT_ALIGN (sizeof (struct fdt_header), 8) + mem_rsv_size
+ + struct_size + fdt_size_dt_strings (fdt);
+
+ if (bufsize < newsize)
+ return -FDT_ERR_NOSPACE;
+
+ /* First attempt to build converted tree at beginning of buffer */
+ tmp = buf;
+ /* But if that overlaps with the old tree... */
+ if (((tmp + newsize) > fdtstart) && (tmp < fdtend))
+ {
+ /* Try right after the old tree instead */
+ tmp = (char *) (uintptr_t) fdtend;
+ if ((tmp + newsize) > ((char *) buf + bufsize))
+ return -FDT_ERR_NOSPACE;
+ }
+
+ _fdt_packblocks (fdt, tmp, mem_rsv_size, struct_size);
+ memmove (buf, tmp, newsize);
+
+ fdt_set_magic (buf, FDT_MAGIC);
+ fdt_set_totalsize (buf, bufsize);
+ fdt_set_version (buf, 17);
+ fdt_set_last_comp_version (buf, 16);
+ fdt_set_boot_cpuid_phys (buf, fdt_boot_cpuid_phys (fdt));
+
+ return 0;
}
-int fdt_pack(void *fdt)
+int
+fdt_pack (void *fdt)
{
- int mem_rsv_size;
+ int mem_rsv_size;
- FDT_RW_CHECK_HEADER(fdt);
+ FDT_RW_CHECK_HEADER (fdt);
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
- _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
- fdt_set_totalsize(fdt, _fdt_data_size(fdt));
+ mem_rsv_size = (fdt_num_mem_rsv (fdt) + 1)
+ * sizeof (struct fdt_reserve_entry);
+ _fdt_packblocks (fdt, fdt, mem_rsv_size, fdt_size_dt_struct (fdt));
+ fdt_set_totalsize (fdt, _fdt_data_size (fdt));
- return 0;
+ return 0;
}
diff --git a/grub-core/lib/dtc/libfdt/fdt_strerror.c b/grub-core/lib/dtc/libfdt/fdt_strerror.c
index e6c3cee..2d8606b 100644
--- a/grub-core/lib/dtc/libfdt/fdt_strerror.c
+++ b/grub-core/lib/dtc/libfdt/fdt_strerror.c
@@ -55,42 +55,46 @@
#include "libfdt_internal.h"
-struct fdt_errtabent {
- const char *str;
+struct fdt_errtabent
+{
+ const char *str;
};
#define FDT_ERRTABENT(val) \
[(val)] = { .str = #val, }
static struct fdt_errtabent fdt_errtable[] = {
- FDT_ERRTABENT(FDT_ERR_NOTFOUND),
- FDT_ERRTABENT(FDT_ERR_EXISTS),
- FDT_ERRTABENT(FDT_ERR_NOSPACE),
+ FDT_ERRTABENT (FDT_ERR_NOTFOUND),
+ FDT_ERRTABENT (FDT_ERR_EXISTS),
+ FDT_ERRTABENT (FDT_ERR_NOSPACE),
- FDT_ERRTABENT(FDT_ERR_BADOFFSET),
- FDT_ERRTABENT(FDT_ERR_BADPATH),
- FDT_ERRTABENT(FDT_ERR_BADSTATE),
+ FDT_ERRTABENT (FDT_ERR_BADOFFSET),
+ FDT_ERRTABENT (FDT_ERR_BADPATH),
+ FDT_ERRTABENT (FDT_ERR_BADSTATE),
- FDT_ERRTABENT(FDT_ERR_TRUNCATED),
- FDT_ERRTABENT(FDT_ERR_BADMAGIC),
- FDT_ERRTABENT(FDT_ERR_BADVERSION),
- FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
- FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
+ FDT_ERRTABENT (FDT_ERR_TRUNCATED),
+ FDT_ERRTABENT (FDT_ERR_BADMAGIC),
+ FDT_ERRTABENT (FDT_ERR_BADVERSION),
+ FDT_ERRTABENT (FDT_ERR_BADSTRUCTURE),
+ FDT_ERRTABENT (FDT_ERR_BADLAYOUT),
};
+
#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
-const char *fdt_strerror(int errval)
+const char *
+fdt_strerror (int errval)
{
- if (errval > 0)
- return "<valid offset/length>";
- else if (errval == 0)
- return "<no error>";
- else if (errval > -FDT_ERRTABSIZE) {
- const char *s = fdt_errtable[-errval].str;
+ if (errval > 0)
+ return "<valid offset/length>";
+ else if (errval == 0)
+ return "<no error>";
+ else if (errval > -FDT_ERRTABSIZE)
+ {
+ const char *s = fdt_errtable[-errval].str;
- if (s)
- return s;
- }
+ if (s)
+ return s;
+ }
- return "<unknown error>";
+ return "<unknown error>";
}
diff --git a/grub-core/lib/dtc/libfdt/fdt_sw.c b/grub-core/lib/dtc/libfdt/fdt_sw.c
index 55ebebf..411d517 100644
--- a/grub-core/lib/dtc/libfdt/fdt_sw.c
+++ b/grub-core/lib/dtc/libfdt/fdt_sw.c
@@ -55,12 +55,13 @@
#include "libfdt_internal.h"
-static int _fdt_sw_check_header(void *fdt)
+static int
+_fdt_sw_check_header (void *fdt)
{
- if (fdt_magic(fdt) != FDT_SW_MAGIC)
- return -FDT_ERR_BADMAGIC;
- /* FIXME: should check more details about the header state */
- return 0;
+ if (fdt_magic (fdt) != FDT_SW_MAGIC)
+ return -FDT_ERR_BADMAGIC;
+ /* FIXME: should check more details about the header state */
+ return 0;
}
#define FDT_SW_CHECK_HEADER(fdt) \
@@ -70,187 +71,197 @@ static int _fdt_sw_check_header(void *fdt)
return err; \
}
-static void *_fdt_grab_space(void *fdt, size_t len)
+static void *
+_fdt_grab_space (void *fdt, size_t len)
{
- int offset = fdt_size_dt_struct(fdt);
- int spaceleft;
+ int offset = fdt_size_dt_struct (fdt);
+ int spaceleft;
- spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
- - fdt_size_dt_strings(fdt);
+ spaceleft = fdt_totalsize (fdt) - fdt_off_dt_struct (fdt)
+ - fdt_size_dt_strings (fdt);
- if ((offset + len < offset) || (offset + len > spaceleft))
- return NULL;
+ if ((offset + len < offset) || (offset + len > spaceleft))
+ return NULL;
- fdt_set_size_dt_struct(fdt, offset + len);
- return _fdt_offset_ptr_w(fdt, offset);
+ fdt_set_size_dt_struct (fdt, offset + len);
+ return _fdt_offset_ptr_w (fdt, offset);
}
-int fdt_create(void *buf, int bufsize)
+int
+fdt_create (void *buf, int bufsize)
{
- void *fdt = buf;
+ void *fdt = buf;
- if (bufsize < sizeof(struct fdt_header))
- return -FDT_ERR_NOSPACE;
+ if (bufsize < sizeof (struct fdt_header))
+ return -FDT_ERR_NOSPACE;
- memset(buf, 0, bufsize);
+ memset (buf, 0, bufsize);
- fdt_set_magic(fdt, FDT_SW_MAGIC);
- fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
- fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
- fdt_set_totalsize(fdt, bufsize);
+ fdt_set_magic (fdt, FDT_SW_MAGIC);
+ fdt_set_version (fdt, FDT_LAST_SUPPORTED_VERSION);
+ fdt_set_last_comp_version (fdt, FDT_FIRST_SUPPORTED_VERSION);
+ fdt_set_totalsize (fdt, bufsize);
- fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
- sizeof(struct fdt_reserve_entry)));
- fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
- fdt_set_off_dt_strings(fdt, bufsize);
+ fdt_set_off_mem_rsvmap (fdt, FDT_ALIGN (sizeof (struct fdt_header),
+ sizeof (struct fdt_reserve_entry)));
+ fdt_set_off_dt_struct (fdt, fdt_off_mem_rsvmap (fdt));
+ fdt_set_off_dt_strings (fdt, bufsize);
- return 0;
+ return 0;
}
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
+int
+fdt_add_reservemap_entry (void *fdt, uint64_t addr, uint64_t size)
{
- struct fdt_reserve_entry *re;
- int offset;
+ struct fdt_reserve_entry *re;
+ int offset;
- FDT_SW_CHECK_HEADER(fdt);
+ FDT_SW_CHECK_HEADER (fdt);
- if (fdt_size_dt_struct(fdt))
- return -FDT_ERR_BADSTATE;
+ if (fdt_size_dt_struct (fdt))
+ return -FDT_ERR_BADSTATE;
- offset = fdt_off_dt_struct(fdt);
- if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
- return -FDT_ERR_NOSPACE;
+ offset = fdt_off_dt_struct (fdt);
+ if ((offset + sizeof (*re)) > fdt_totalsize (fdt))
+ return -FDT_ERR_NOSPACE;
- re = (struct fdt_reserve_entry *)((char *)fdt + offset);
- re->address = cpu_to_fdt64(addr);
- re->size = cpu_to_fdt64(size);
+ re = (struct fdt_reserve_entry *) ((char *) fdt + offset);
+ re->address = cpu_to_fdt64 (addr);
+ re->size = cpu_to_fdt64 (size);
- fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
+ fdt_set_off_dt_struct (fdt, offset + sizeof (*re));
- return 0;
+ return 0;
}
-int fdt_finish_reservemap(void *fdt)
+int
+fdt_finish_reservemap (void *fdt)
{
- return fdt_add_reservemap_entry(fdt, 0, 0);
+ return fdt_add_reservemap_entry (fdt, 0, 0);
}
-int fdt_begin_node(void *fdt, const char *name)
+int
+fdt_begin_node (void *fdt, const char *name)
{
- struct fdt_node_header *nh;
- int namelen = strlen(name) + 1;
+ struct fdt_node_header *nh;
+ int namelen = strlen (name) + 1;
- FDT_SW_CHECK_HEADER(fdt);
+ FDT_SW_CHECK_HEADER (fdt);
- nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
- if (! nh)
- return -FDT_ERR_NOSPACE;
+ nh = _fdt_grab_space (fdt, sizeof (*nh) + FDT_TAGALIGN (namelen));
+ if (!nh)
+ return -FDT_ERR_NOSPACE;
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memcpy(nh->name, name, namelen);
- return 0;
+ nh->tag = cpu_to_fdt32 (FDT_BEGIN_NODE);
+ memcpy (nh->name, name, namelen);
+ return 0;
}
-int fdt_end_node(void *fdt)
+int
+fdt_end_node (void *fdt)
{
- uint32_t *en;
+ uint32_t *en;
- FDT_SW_CHECK_HEADER(fdt);
+ FDT_SW_CHECK_HEADER (fdt);
- en = _fdt_grab_space(fdt, FDT_TAGSIZE);
- if (! en)
- return -FDT_ERR_NOSPACE;
+ en = _fdt_grab_space (fdt, FDT_TAGSIZE);
+ if (!en)
+ return -FDT_ERR_NOSPACE;
- *en = cpu_to_fdt32(FDT_END_NODE);
- return 0;
+ *en = cpu_to_fdt32 (FDT_END_NODE);
+ return 0;
}
-static int _fdt_find_add_string(void *fdt, const char *s)
+static int
+_fdt_find_add_string (void *fdt, const char *s)
{
- char *strtab = (char *)fdt + fdt_totalsize(fdt);
- const char *p;
- int strtabsize = fdt_size_dt_strings(fdt);
- int len = strlen(s) + 1;
- int struct_top, offset;
-
- p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
- if (p)
- return p - strtab;
-
- /* Add it */
- offset = -strtabsize - len;
- struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- if (fdt_totalsize(fdt) + offset < struct_top)
- return 0; /* no more room :( */
-
- memcpy(strtab + offset, s, len);
- fdt_set_size_dt_strings(fdt, strtabsize + len);
- return offset;
+ char *strtab = (char *) fdt + fdt_totalsize (fdt);
+ const char *p;
+ int strtabsize = fdt_size_dt_strings (fdt);
+ int len = strlen (s) + 1;
+ int struct_top, offset;
+
+ p = _fdt_find_string (strtab - strtabsize, strtabsize, s);
+ if (p)
+ return p - strtab;
+
+ /* Add it */
+ offset = -strtabsize - len;
+ struct_top = fdt_off_dt_struct (fdt) + fdt_size_dt_struct (fdt);
+ if (fdt_totalsize (fdt) + offset < struct_top)
+ return 0; /* no more room :( */
+
+ memcpy (strtab + offset, s, len);
+ fdt_set_size_dt_strings (fdt, strtabsize + len);
+ return offset;
}
-int fdt_property(void *fdt, const char *name, const void *val, int len)
+int
+fdt_property (void *fdt, const char *name, const void *val, int len)
{
- struct fdt_property *prop;
- int nameoff;
+ struct fdt_property *prop;
+ int nameoff;
- FDT_SW_CHECK_HEADER(fdt);
+ FDT_SW_CHECK_HEADER (fdt);
- nameoff = _fdt_find_add_string(fdt, name);
- if (nameoff == 0)
- return -FDT_ERR_NOSPACE;
+ nameoff = _fdt_find_add_string (fdt, name);
+ if (nameoff == 0)
+ return -FDT_ERR_NOSPACE;
- prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
- if (! prop)
- return -FDT_ERR_NOSPACE;
+ prop = _fdt_grab_space (fdt, sizeof (*prop) + FDT_TAGALIGN (len));
+ if (!prop)
+ return -FDT_ERR_NOSPACE;
- prop->tag = cpu_to_fdt32(FDT_PROP);
- prop->nameoff = cpu_to_fdt32(nameoff);
- prop->len = cpu_to_fdt32(len);
- memcpy(prop->data, val, len);
- return 0;
+ prop->tag = cpu_to_fdt32 (FDT_PROP);
+ prop->nameoff = cpu_to_fdt32 (nameoff);
+ prop->len = cpu_to_fdt32 (len);
+ memcpy (prop->data, val, len);
+ return 0;
}
-int fdt_finish(void *fdt)
+int
+fdt_finish (void *fdt)
{
- char *p = (char *)fdt;
- uint32_t *end;
- int oldstroffset, newstroffset;
- uint32_t tag;
- int offset, nextoffset;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- /* Add terminator */
- end = _fdt_grab_space(fdt, sizeof(*end));
- if (! end)
- return -FDT_ERR_NOSPACE;
- *end = cpu_to_fdt32(FDT_END);
-
- /* Relocate the string table */
- oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
- newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
- fdt_set_off_dt_strings(fdt, newstroffset);
-
- /* Walk the structure, correcting string offsets */
- offset = 0;
- while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
- if (tag == FDT_PROP) {
- struct fdt_property *prop =
- _fdt_offset_ptr_w(fdt, offset);
- int nameoff;
-
- nameoff = fdt32_to_cpu(prop->nameoff);
- nameoff += fdt_size_dt_strings(fdt);
- prop->nameoff = cpu_to_fdt32(nameoff);
- }
- offset = nextoffset;
+ char *p = (char *) fdt;
+ uint32_t *end;
+ int oldstroffset, newstroffset;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ FDT_SW_CHECK_HEADER (fdt);
+
+ /* Add terminator */
+ end = _fdt_grab_space (fdt, sizeof (*end));
+ if (!end)
+ return -FDT_ERR_NOSPACE;
+ *end = cpu_to_fdt32 (FDT_END);
+
+ /* Relocate the string table */
+ oldstroffset = fdt_totalsize (fdt) - fdt_size_dt_strings (fdt);
+ newstroffset = fdt_off_dt_struct (fdt) + fdt_size_dt_struct (fdt);
+ memmove (p + newstroffset, p + oldstroffset, fdt_size_dt_strings (fdt));
+ fdt_set_off_dt_strings (fdt, newstroffset);
+
+ /* Walk the structure, correcting string offsets */
+ offset = 0;
+ while ((tag = fdt_next_tag (fdt, offset, &nextoffset)) != FDT_END)
+ {
+ if (tag == FDT_PROP)
+ {
+ struct fdt_property *prop = _fdt_offset_ptr_w (fdt, offset);
+ int nameoff;
+
+ nameoff = fdt32_to_cpu (prop->nameoff);
+ nameoff += fdt_size_dt_strings (fdt);
+ prop->nameoff = cpu_to_fdt32 (nameoff);
}
- if (nextoffset < 0)
- return nextoffset;
-
- /* Finally, adjust the header */
- fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
- fdt_set_magic(fdt, FDT_MAGIC);
- return 0;
+ offset = nextoffset;
+ }
+ if (nextoffset < 0)
+ return nextoffset;
+
+ /* Finally, adjust the header */
+ fdt_set_totalsize (fdt, newstroffset + fdt_size_dt_strings (fdt));
+ fdt_set_magic (fdt, FDT_MAGIC);
+ return 0;
}
diff --git a/grub-core/lib/dtc/libfdt/fdt_wip.c b/grub-core/lib/dtc/libfdt/fdt_wip.c
index 6025fa1..09297d9 100644
--- a/grub-core/lib/dtc/libfdt/fdt_wip.c
+++ b/grub-core/lib/dtc/libfdt/fdt_wip.c
@@ -55,64 +55,69 @@
#include "libfdt_internal.h"
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int
+fdt_setprop_inplace (void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
{
- void *propval;
- int proplen;
+ void *propval;
+ int proplen;
- propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
- if (! propval)
- return proplen;
+ propval = fdt_getprop_w (fdt, nodeoffset, name, &proplen);
+ if (!propval)
+ return proplen;
- if (proplen != len)
- return -FDT_ERR_NOSPACE;
+ if (proplen != len)
+ return -FDT_ERR_NOSPACE;
- memcpy(propval, val, len);
- return 0;
+ memcpy (propval, val, len);
+ return 0;
}
-static void _fdt_nop_region(void *start, int len)
+static void
+_fdt_nop_region (void *start, int len)
{
- uint32_t *p;
+ uint32_t *p;
- for (p = start; (char *)p < ((char *)start + len); p++)
- *p = cpu_to_fdt32(FDT_NOP);
+ for (p = start; (char *) p < ((char *) start + len); p++)
+ *p = cpu_to_fdt32 (FDT_NOP);
}
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
+int
+fdt_nop_property (void *fdt, int nodeoffset, const char *name)
{
- struct fdt_property *prop;
- int len;
+ struct fdt_property *prop;
+ int len;
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
- return len;
+ prop = fdt_get_property_w (fdt, nodeoffset, name, &len);
+ if (!prop)
+ return len;
- _fdt_nop_region(prop, len + sizeof(*prop));
+ _fdt_nop_region (prop, len + sizeof (*prop));
- return 0;
+ return 0;
}
-int _fdt_node_end_offset(void *fdt, int offset)
+int
+_fdt_node_end_offset (void *fdt, int offset)
{
- int depth = 0;
+ int depth = 0;
- while ((offset >= 0) && (depth >= 0))
- offset = fdt_next_node(fdt, offset, &depth);
+ while ((offset >= 0) && (depth >= 0))
+ offset = fdt_next_node (fdt, offset, &depth);
- return offset;
+ return offset;
}
-int fdt_nop_node(void *fdt, int nodeoffset)
+int
+fdt_nop_node (void *fdt, int nodeoffset)
{
- int endoffset;
+ int endoffset;
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
+ endoffset = _fdt_node_end_offset (fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
- _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
- endoffset - nodeoffset);
- return 0;
+ _fdt_nop_region (fdt_offset_ptr_w (fdt, nodeoffset, 0),
+ endoffset - nodeoffset);
+ return 0;
}
diff --git a/grub-core/lib/dtc/libfdt/libfdt.h b/grub-core/lib/dtc/libfdt/libfdt.h
index 55f3eb3..6b9bfb5 100644
--- a/grub-core/lib/dtc/libfdt/libfdt.h
+++ b/grub-core/lib/dtc/libfdt/libfdt.h
@@ -122,19 +122,21 @@
/* Low-level functions (you probably don't need these) */
/**********************************************************************/
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
-static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
+const void *fdt_offset_ptr (const void *fdt, int offset,
+ unsigned int checklen);
+static inline void *
+fdt_offset_ptr_w (void *fdt, int offset, int checklen)
{
- return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
+ return (void *) (uintptr_t) fdt_offset_ptr (fdt, offset, checklen);
}
-uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
+uint32_t fdt_next_tag (const void *fdt, int offset, int *nextoffset);
/**********************************************************************/
/* Traversal functions */
/**********************************************************************/
-int fdt_next_node(const void *fdt, int offset, int *depth);
+int fdt_next_node (const void *fdt, int offset, int *depth);
/**********************************************************************/
/* General functions */
@@ -159,16 +161,16 @@ int fdt_next_node(const void *fdt, int offset, int *depth);
struct fdt_header *fdth = (struct fdt_header*)fdt; \
fdth->name = cpu_to_fdt32(val); \
}
-__fdt_set_hdr(magic);
-__fdt_set_hdr(totalsize);
-__fdt_set_hdr(off_dt_struct);
-__fdt_set_hdr(off_dt_strings);
-__fdt_set_hdr(off_mem_rsvmap);
-__fdt_set_hdr(version);
-__fdt_set_hdr(last_comp_version);
-__fdt_set_hdr(boot_cpuid_phys);
-__fdt_set_hdr(size_dt_strings);
-__fdt_set_hdr(size_dt_struct);
+__fdt_set_hdr (magic);
+__fdt_set_hdr (totalsize);
+__fdt_set_hdr (off_dt_struct);
+__fdt_set_hdr (off_dt_strings);
+__fdt_set_hdr (off_mem_rsvmap);
+__fdt_set_hdr (version);
+__fdt_set_hdr (last_comp_version);
+__fdt_set_hdr (boot_cpuid_phys);
+__fdt_set_hdr (size_dt_strings);
+__fdt_set_hdr (size_dt_struct);
#undef __fdt_set_hdr
/**
@@ -185,7 +187,7 @@ __fdt_set_hdr(size_dt_struct);
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE, standard meanings, as above
*/
-int fdt_check_header(const void *fdt);
+int fdt_check_header (const void *fdt);
/**
* fdt_move - move a device tree around in memory
@@ -206,7 +208,7 @@ int fdt_check_header(const void *fdt);
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE, standard meanings
*/
-int fdt_move(const void *fdt, void *buf, int bufsize);
+int fdt_move (const void *fdt, void *buf, int bufsize);
/**********************************************************************/
/* Read-only functions */
@@ -224,7 +226,7 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
* a pointer to the string, on success
* NULL, if stroffset is out of bounds
*/
-const char *fdt_string(const void *fdt, int stroffset);
+const char *fdt_string (const void *fdt, int stroffset);
/**
* fdt_num_mem_rsv - retrieve the number of memory reserve map entries
@@ -237,7 +239,7 @@ const char *fdt_string(const void *fdt, int stroffset);
* returns:
* the number of entries
*/
-int fdt_num_mem_rsv(const void *fdt);
+int fdt_num_mem_rsv (const void *fdt);
/**
* fdt_get_mem_rsv - retrieve one memory reserve map entry
@@ -254,7 +256,8 @@ int fdt_num_mem_rsv(const void *fdt);
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE, standard meanings
*/
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
+int fdt_get_mem_rsv (const void *fdt, int n, uint64_t * address,
+ uint64_t * size);
/**
* fdt_subnode_offset_namelen - find a subnode based on substring
@@ -268,8 +271,8 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
* useful for finding subnodes based on a portion of a larger string,
* such as a full path.
*/
-int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
- const char *name, int namelen);
+int fdt_subnode_offset_namelen (const void *fdt, int parentoffset,
+ const char *name, int namelen);
/**
* fdt_subnode_offset - find a subnode of a given node
* @fdt: pointer to the device tree blob
@@ -293,7 +296,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings.
*/
-int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
+int fdt_subnode_offset (const void *fdt, int parentoffset, const char *name);
/**
* fdt_path_offset - find a tree node by its full path
@@ -317,7 +320,7 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings.
*/
-int fdt_path_offset(const void *fdt, const char *path);
+int fdt_path_offset (const void *fdt, const char *path);
/**
* fdt_get_name - retrieve the name of a given node
@@ -340,7 +343,7 @@ int fdt_path_offset(const void *fdt, const char *path);
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE, standard meanings
*/
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
+const char *fdt_get_name (const void *fdt, int nodeoffset, int *lenp);
/**
* fdt_first_property_offset - find the offset of a node's first property
@@ -360,7 +363,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings.
*/
-int fdt_first_property_offset(const void *fdt, int nodeoffset);
+int fdt_first_property_offset (const void *fdt, int nodeoffset);
/**
* fdt_next_property_offset - step through a node's properties
@@ -381,7 +384,7 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset);
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings.
*/
-int fdt_next_property_offset(const void *fdt, int offset);
+int fdt_next_property_offset (const void *fdt, int offset);
/**
* fdt_get_property_by_offset - retrieve the property at a given offset
@@ -407,9 +410,8 @@ int fdt_next_property_offset(const void *fdt, int offset);
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
- int offset,
- int *lenp);
+const struct fdt_property *fdt_get_property_by_offset (const void *fdt,
+ int offset, int *lenp);
/**
* fdt_get_property_namelen - find a property based on substring
@@ -422,10 +424,10 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
* Identical to fdt_get_property_namelen(), but only examine the first
* namelen characters of name for matching the property name.
*/
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
- int nodeoffset,
- const char *name,
- int namelen, int *lenp);
+const struct fdt_property *fdt_get_property_namelen (const void *fdt,
+ int nodeoffset,
+ const char *name,
+ int namelen, int *lenp);
/**
* fdt_get_property - find a given property in a given node
@@ -454,14 +456,13 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
- const char *name, int *lenp);
-static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
- const char *name,
- int *lenp)
+const struct fdt_property *fdt_get_property (const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+static inline struct fdt_property *
+fdt_get_property_w (void *fdt, int nodeoffset, const char *name, int *lenp)
{
- return (struct fdt_property *)(uintptr_t)
- fdt_get_property(fdt, nodeoffset, name, lenp);
+ return (struct fdt_property *) (uintptr_t)
+ fdt_get_property (fdt, nodeoffset, name, lenp);
}
/**
@@ -495,8 +496,8 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-const void *fdt_getprop_by_offset(const void *fdt, int offset,
- const char **namep, int *lenp);
+const void *fdt_getprop_by_offset (const void *fdt, int offset,
+ const char **namep, int *lenp);
/**
* fdt_getprop_namelen - get property value based on substring
@@ -509,8 +510,8 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
* Identical to fdt_getprop(), but only examine the first namelen
* characters of name for matching the property name.
*/
-const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
- const char *name, int namelen, int *lenp);
+const void *fdt_getprop_namelen (const void *fdt, int nodeoffset,
+ const char *name, int namelen, int *lenp);
/**
* fdt_getprop - retrieve the value of a given property
@@ -539,12 +540,12 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-const void *fdt_getprop(const void *fdt, int nodeoffset,
- const char *name, int *lenp);
-static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
- const char *name, int *lenp)
+const void *fdt_getprop (const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+static inline void *
+fdt_getprop_w (void *fdt, int nodeoffset, const char *name, int *lenp)
{
- return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
+ return (void *) (uintptr_t) fdt_getprop (fdt, nodeoffset, name, lenp);
}
/**
@@ -559,7 +560,7 @@ static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
* the phandle of the node at nodeoffset, on success (!= 0, != -1)
* 0, if the node has no phandle, or another error occurs
*/
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
+uint32_t fdt_get_phandle (const void *fdt, int nodeoffset);
/**
* fdt_get_alias_namelen - get alias based on substring
@@ -570,8 +571,8 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
* Identical to fdt_get_alias(), but only examine the first namelen
* characters of name for matching the alias name.
*/
-const char *fdt_get_alias_namelen(const void *fdt,
- const char *name, int namelen);
+const char *fdt_get_alias_namelen (const void *fdt,
+ const char *name, int namelen);
/**
* fdt_get_alias - retreive the path referenced by a given alias
@@ -585,7 +586,7 @@ const char *fdt_get_alias_namelen(const void *fdt,
* a pointer to the expansion of the alias named 'name', of it exists
* NULL, if the given alias or the /aliases node does not exist
*/
-const char *fdt_get_alias(const void *fdt, const char *name);
+const char *fdt_get_alias (const void *fdt, const char *name);
/**
* fdt_get_path - determine the full path of a node
@@ -612,7 +613,7 @@ const char *fdt_get_alias(const void *fdt, const char *name);
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE, standard meanings
*/
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
+int fdt_get_path (const void *fdt, int nodeoffset, char *buf, int buflen);
/**
* fdt_supernode_atdepth_offset - find a specific ancestor of a node
@@ -644,8 +645,8 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE, standard meanings
*/
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
- int supernodedepth, int *nodedepth);
+int fdt_supernode_atdepth_offset (const void *fdt, int nodeoffset,
+ int supernodedepth, int *nodedepth);
/**
* fdt_node_depth - find the depth of a given node
@@ -666,7 +667,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE, standard meanings
*/
-int fdt_node_depth(const void *fdt, int nodeoffset);
+int fdt_node_depth (const void *fdt, int nodeoffset);
/**
* fdt_parent_offset - find the parent of a given node
@@ -689,7 +690,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset);
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE, standard meanings
*/
-int fdt_parent_offset(const void *fdt, int nodeoffset);
+int fdt_parent_offset (const void *fdt, int nodeoffset);
/**
* fdt_node_offset_by_prop_value - find nodes with a given property value
@@ -729,9 +730,9 @@ int fdt_parent_offset(const void *fdt, int nodeoffset);
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE, standard meanings
*/
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
- const char *propname,
- const void *propval, int proplen);
+int fdt_node_offset_by_prop_value (const void *fdt, int startoffset,
+ const char *propname,
+ const void *propval, int proplen);
/**
* fdt_node_offset_by_phandle - find the node with a given phandle
@@ -752,7 +753,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE, standard meanings
*/
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
+int fdt_node_offset_by_phandle (const void *fdt, uint32_t phandle);
/**
* fdt_node_check_compatible: check a node's compatible property
@@ -776,8 +777,8 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE, standard meanings
*/
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
- const char *compatible);
+int fdt_node_check_compatible (const void *fdt, int nodeoffset,
+ const char *compatible);
/**
* fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
@@ -813,8 +814,8 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE, standard meanings
*/
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
- const char *compatible);
+int fdt_node_offset_by_compatible (const void *fdt, int startoffset,
+ const char *compatible);
/**********************************************************************/
/* Write-in-place functions */
@@ -848,8 +849,8 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
+int fdt_setprop_inplace (void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
/**
* fdt_setprop_inplace_cell - change the value of a single-cell property
@@ -879,11 +880,12 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
+static inline int
+fdt_setprop_inplace_cell (void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
{
- val = cpu_to_fdt32(val);
- return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+ val = cpu_to_fdt32 (val);
+ return fdt_setprop_inplace (fdt, nodeoffset, name, &val, sizeof (val));
}
/**
@@ -910,7 +912,7 @@ static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
+int fdt_nop_property (void *fdt, int nodeoffset, const char *name);
/**
* fdt_nop_node - replace a node (subtree) with nop tags
@@ -934,33 +936,35 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_nop_node(void *fdt, int nodeoffset);
+int fdt_nop_node (void *fdt, int nodeoffset);
/**********************************************************************/
/* Sequential write functions */
/**********************************************************************/
-int fdt_create(void *buf, int bufsize);
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
-int fdt_finish_reservemap(void *fdt);
-int fdt_begin_node(void *fdt, const char *name);
-int fdt_property(void *fdt, const char *name, const void *val, int len);
-static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+int fdt_create (void *buf, int bufsize);
+int fdt_add_reservemap_entry (void *fdt, uint64_t addr, uint64_t size);
+int fdt_finish_reservemap (void *fdt);
+int fdt_begin_node (void *fdt, const char *name);
+int fdt_property (void *fdt, const char *name, const void *val, int len);
+static inline int
+fdt_property_cell (void *fdt, const char *name, uint32_t val)
{
- val = cpu_to_fdt32(val);
- return fdt_property(fdt, name, &val, sizeof(val));
+ val = cpu_to_fdt32 (val);
+ return fdt_property (fdt, name, &val, sizeof (val));
}
+
#define fdt_property_string(fdt, name, str) \
fdt_property(fdt, name, str, strlen(str)+1)
-int fdt_end_node(void *fdt);
-int fdt_finish(void *fdt);
+int fdt_end_node (void *fdt);
+int fdt_finish (void *fdt);
/**********************************************************************/
/* Read-write functions */
/**********************************************************************/
-int fdt_open_into(const void *fdt, void *buf, int bufsize);
-int fdt_pack(void *fdt);
+int fdt_open_into (const void *fdt, void *buf, int bufsize);
+int fdt_pack (void *fdt);
/**
* fdt_add_mem_rsv - add one memory reserve map entry
@@ -984,7 +988,7 @@ int fdt_pack(void *fdt);
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
+int fdt_add_mem_rsv (void *fdt, uint64_t address, uint64_t size);
/**
* fdt_del_mem_rsv - remove a memory reserve map entry
@@ -1008,7 +1012,7 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_del_mem_rsv(void *fdt, int n);
+int fdt_del_mem_rsv (void *fdt, int n);
/**
* fdt_set_name - change the name of a given node
@@ -1034,7 +1038,7 @@ int fdt_del_mem_rsv(void *fdt, int n);
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE, standard meanings
*/
-int fdt_set_name(void *fdt, int nodeoffset, const char *name);
+int fdt_set_name (void *fdt, int nodeoffset, const char *name);
/**
* fdt_setprop - create or change a property
@@ -1064,8 +1068,8 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name);
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
+int fdt_setprop (void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
/**
* fdt_setprop_cell - set a property to a single cell value
@@ -1095,11 +1099,11 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
- uint32_t val)
+static inline int
+fdt_setprop_cell (void *fdt, int nodeoffset, const char *name, uint32_t val)
{
- val = cpu_to_fdt32(val);
- return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+ val = cpu_to_fdt32 (val);
+ return fdt_setprop (fdt, nodeoffset, name, &val, sizeof (val));
}
/**
@@ -1155,7 +1159,7 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_delprop(void *fdt, int nodeoffset, const char *name);
+int fdt_delprop (void *fdt, int nodeoffset, const char *name);
/**
* fdt_add_subnode_namelen - creates a new node based on substring
@@ -1169,8 +1173,8 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name);
* creating subnodes based on a portion of a larger string, such as a
* full path.
*/
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
- const char *name, int namelen);
+int fdt_add_subnode_namelen (void *fdt, int parentoffset,
+ const char *name, int namelen);
/**
* fdt_add_subnode - creates a new node
@@ -1201,7 +1205,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings.
*/
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
+int fdt_add_subnode (void *fdt, int parentoffset, const char *name);
/**
* fdt_del_node - delete a node (subtree)
@@ -1224,12 +1228,12 @@ int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_del_node(void *fdt, int nodeoffset);
+int fdt_del_node (void *fdt, int nodeoffset);
/**********************************************************************/
/* Debugging / informational functions */
/**********************************************************************/
-const char *fdt_strerror(int errval);
+const char *fdt_strerror (int errval);
#endif /* _LIBFDT_H */
diff --git a/grub-core/lib/dtc/libfdt/libfdt_env.h b/grub-core/lib/dtc/libfdt/libfdt_env.h
index 449bf60..bf66ffd 100644
--- a/grub-core/lib/dtc/libfdt/libfdt_env.h
+++ b/grub-core/lib/dtc/libfdt/libfdt_env.h
@@ -6,17 +6,21 @@
#include <string.h>
#define _B(n) ((unsigned long long)((uint8_t *)&x)[n])
-static inline uint32_t fdt32_to_cpu(uint32_t x)
+static inline uint32_t
+fdt32_to_cpu (uint32_t x)
{
- return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3);
+ return (_B (0) << 24) | (_B (1) << 16) | (_B (2) << 8) | _B (3);
}
+
#define cpu_to_fdt32(x) fdt32_to_cpu(x)
-static inline uint64_t fdt64_to_cpu(uint64_t x)
+static inline uint64_t
+fdt64_to_cpu (uint64_t x)
{
- return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32)
- | (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7);
+ return (_B (0) << 56) | (_B (1) << 48) | (_B (2) << 40) | (_B (3) << 32)
+ | (_B (4) << 24) | (_B (5) << 16) | (_B (6) << 8) | _B (7);
}
+
#define cpu_to_fdt64(x) fdt64_to_cpu(x)
#undef _B
diff --git a/grub-core/lib/dtc/libfdt/libfdt_internal.h b/grub-core/lib/dtc/libfdt/libfdt_internal.h
index 381133b..b197032 100644
--- a/grub-core/lib/dtc/libfdt/libfdt_internal.h
+++ b/grub-core/lib/dtc/libfdt/libfdt_internal.h
@@ -62,32 +62,37 @@
return err; \
}
-int _fdt_check_node_offset(const void *fdt, int offset);
-int _fdt_check_prop_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
+int _fdt_check_node_offset (const void *fdt, int offset);
+int _fdt_check_prop_offset (const void *fdt, int offset);
+const char *_fdt_find_string (const char *strtab, int tabsize, const char *s);
+int _fdt_node_end_offset (void *fdt, int nodeoffset);
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
+static inline const void *
+_fdt_offset_ptr (const void *fdt, int offset)
{
- return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
+ return (const char *) fdt + fdt_off_dt_struct (fdt) + offset;
}
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
+static inline void *
+_fdt_offset_ptr_w (void *fdt, int offset)
{
- return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
+ return (void *) (uintptr_t) _fdt_offset_ptr (fdt, offset);
}
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
+static inline const struct fdt_reserve_entry *
+_fdt_mem_rsv (const void *fdt, int n)
{
- const struct fdt_reserve_entry *rsv_table =
- (const struct fdt_reserve_entry *)
- ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
+ const struct fdt_reserve_entry *rsv_table =
+ (const struct fdt_reserve_entry *)
+ ((const char *) fdt + fdt_off_mem_rsvmap (fdt));
- return rsv_table + n;
+ return rsv_table + n;
}
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
+
+static inline struct fdt_reserve_entry *
+_fdt_mem_rsv_w (void *fdt, int n)
{
- return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
+ return (void *) (uintptr_t) _fdt_mem_rsv (fdt, n);
}
#define FDT_SW_MAGIC (~FDT_MAGIC)
diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c
index df25b30..0170eed 100644
--- a/grub-core/lib/i386/relocator.c
+++ b/grub-core/lib/i386/relocator.c
@@ -54,6 +54,7 @@ extern grub_uint16_t grub_relocator16_sp;
extern grub_uint32_t grub_relocator16_edx;
extern grub_uint32_t grub_relocator16_ebx;
extern grub_uint32_t grub_relocator16_esi;
+extern grub_uint32_t grub_relocator16_ebp;
extern grub_uint16_t grub_relocator16_keep_a20_enabled;
@@ -225,6 +226,7 @@ grub_relocator16_boot (struct grub_relocator *rel,
grub_relocator16_ss = state.ss;
grub_relocator16_sp = state.sp;
+ grub_relocator16_ebp = state.ebp;
grub_relocator16_ebx = state.ebx;
grub_relocator16_edx = state.edx;
grub_relocator16_esi = state.esi;
diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S
index e79d875..c8d6f86 100644
--- a/grub-core/lib/i386/relocator16.S
+++ b/grub-core/lib/i386/relocator16.S
@@ -259,6 +259,11 @@ VARIABLE(grub_relocator16_edx)
VARIABLE(grub_relocator16_ebx)
.long 0
+ /* movl imm32, %ebp. */
+ .byte 0x66, 0xbd
+VARIABLE(grub_relocator16_ebp)
+ .long 0
+
/* Cleared direction flag is of no problem with any current
payload and makes this implementation easier. */
cld
diff --git a/grub-core/lib/ieee1275/cmos.c b/grub-core/lib/ieee1275/cmos.c
index fa57db9..328d70a 100644
--- a/grub-core/lib/ieee1275/cmos.c
+++ b/grub-core/lib/ieee1275/cmos.c
@@ -23,51 +23,53 @@
#include <grub/misc.h>
volatile grub_uint8_t *grub_cmos_port = 0;
-grub_err_t
-grub_cmos_find_port (void)
+
+/* Helper for grub_cmos_find_port. */
+static int
+grub_cmos_find_port_iter (struct grub_ieee1275_devalias *alias)
{
- auto int hook (struct grub_ieee1275_devalias *alias);
- int hook (struct grub_ieee1275_devalias *alias)
- {
- grub_ieee1275_phandle_t dev;
- grub_uint32_t addr[2];
- grub_ssize_t actual;
- /* Enough to check if it's "m5819" */
- char compat[100];
- if (grub_ieee1275_finddevice (alias->path, &dev))
- return 0;
- if (grub_ieee1275_get_property (dev, "compatible", compat, sizeof (compat),
- 0))
- return 0;
- if (grub_strcmp (compat, "m5819") != 0)
- return 0;
- if (grub_ieee1275_get_integer_property (dev, "address",
- addr, sizeof (addr), &actual))
- return 0;
- if (actual == 4)
- {
- grub_cmos_port = (volatile grub_uint8_t *) (grub_addr_t) addr[0];
- return 1;
- }
+ grub_ieee1275_phandle_t dev;
+ grub_uint32_t addr[2];
+ grub_ssize_t actual;
+ /* Enough to check if it's "m5819" */
+ char compat[100];
+ if (grub_ieee1275_finddevice (alias->path, &dev))
+ return 0;
+ if (grub_ieee1275_get_property (dev, "compatible", compat, sizeof (compat),
+ 0))
+ return 0;
+ if (grub_strcmp (compat, "m5819") != 0)
+ return 0;
+ if (grub_ieee1275_get_integer_property (dev, "address",
+ addr, sizeof (addr), &actual))
+ return 0;
+ if (actual == 4)
+ {
+ grub_cmos_port = (volatile grub_uint8_t *) (grub_addr_t) addr[0];
+ return 1;
+ }
#if GRUB_CPU_SIZEOF_VOID_P == 8
- if (actual == 8)
- {
- grub_cmos_port = (volatile grub_uint8_t *)
- ((((grub_addr_t) addr[0]) << 32) | addr[1]);
- return 1;
- }
+ if (actual == 8)
+ {
+ grub_cmos_port = (volatile grub_uint8_t *)
+ ((((grub_addr_t) addr[0]) << 32) | addr[1]);
+ return 1;
+ }
#else
- if (actual == 8 && addr[0] == 0)
- {
- grub_cmos_port = (volatile grub_uint8_t *) addr[1];
- return 1;
- }
+ if (actual == 8 && addr[0] == 0)
+ {
+ grub_cmos_port = (volatile grub_uint8_t *) addr[1];
+ return 1;
+ }
#endif
- return 0;
- }
-
- grub_ieee1275_devices_iterate (hook);
+ return 0;
+}
+
+grub_err_t
+grub_cmos_find_port (void)
+{
+ grub_ieee1275_devices_iterate (grub_cmos_find_port_iter);
if (!grub_cmos_port)
return grub_error (GRUB_ERR_IO, "no cmos found");
diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c
index 8792429..74578f1 100644
--- a/grub-core/lib/ieee1275/datetime.c
+++ b/grub-core/lib/ieee1275/datetime.c
@@ -30,22 +30,23 @@ GRUB_MOD_LICENSE ("GPLv3+");
static char *rtc = 0;
static int no_ieee1275_rtc = 0;
+/* Helper for find_rtc. */
+static int
+find_rtc_iter (struct grub_ieee1275_devalias *alias)
+{
+ if (grub_strcmp (alias->type, "rtc") == 0)
+ {
+ grub_dprintf ("datetime", "Found RTC %s\n", alias->path);
+ rtc = grub_strdup (alias->path);
+ return 1;
+ }
+ return 0;
+}
+
static void
find_rtc (void)
{
- auto int hook (struct grub_ieee1275_devalias *alias);
- int hook (struct grub_ieee1275_devalias *alias)
- {
- if (grub_strcmp (alias->type, "rtc") == 0)
- {
- grub_dprintf ("datetime", "Found RTC %s\n", alias->path);
- rtc = grub_strdup (alias->path);
- return 1;
- }
- return 0;
- }
-
- grub_ieee1275_devices_iterate (hook);
+ grub_ieee1275_devices_iterate (find_rtc_iter);
if (!rtc)
no_ieee1275_rtc = 1;
}
diff --git a/grub-core/lib/ieee1275/relocator.c b/grub-core/lib/ieee1275/relocator.c
index 021f0ce..f6ecadd 100644
--- a/grub-core/lib/ieee1275/relocator.c
+++ b/grub-core/lib/ieee1275/relocator.c
@@ -21,65 +21,81 @@
#include <grub/memory.h>
#include <grub/ieee1275/ieee1275.h>
+/* Helper for grub_relocator_firmware_get_max_events. */
+static int
+count (grub_uint64_t addr __attribute__ ((unused)),
+ grub_uint64_t len __attribute__ ((unused)),
+ grub_memory_type_t type __attribute__ ((unused)), void *data)
+{
+ int *counter = data;
+
+ (*counter)++;
+ return 0;
+}
+
unsigned
grub_relocator_firmware_get_max_events (void)
{
int counter = 0;
- auto int NESTED_FUNC_ATTR count (grub_uint64_t addr __attribute__ ((unused)),
- grub_uint64_t len __attribute__ ((unused)),
- grub_memory_type_t type __attribute__ ((unused)));
- int NESTED_FUNC_ATTR count (grub_uint64_t addr __attribute__ ((unused)),
- grub_uint64_t len __attribute__ ((unused)),
- grub_memory_type_t type __attribute__ ((unused)))
- {
- counter++;
- return 0;
- }
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
return 0;
- grub_machine_mmap_iterate (count);
+ grub_machine_mmap_iterate (count, &counter);
return 2 * counter;
}
-unsigned
-grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
+/* Context for grub_relocator_firmware_fill_events. */
+struct grub_relocator_firmware_fill_events_ctx
{
- int counter = 0;
- auto int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len,
- grub_memory_type_t type);
- int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len,
- grub_memory_type_t type)
- {
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
-
- if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
- {
- if (addr + len <= 0x180000)
- return 0;
-
- if (addr < 0x180000)
- {
- len = addr + len - 0x180000;
- addr = 0x180000;
- }
- }
-
- events[counter].type = REG_FIRMWARE_START;
- events[counter].pos = addr;
- counter++;
- events[counter].type = REG_FIRMWARE_END;
- events[counter].pos = addr + len;
- counter++;
+ struct grub_relocator_mmap_event *events;
+ int counter;
+};
+
+/* Helper for grub_relocator_firmware_fill_events. */
+static int
+grub_relocator_firmware_fill_events_iter (grub_uint64_t addr,
+ grub_uint64_t len,
+ grub_memory_type_t type, void *data)
+{
+ struct grub_relocator_firmware_fill_events_ctx *ctx = data;
+ if (type != GRUB_MEMORY_AVAILABLE)
return 0;
- }
+
+ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
+ {
+ if (addr + len <= 0x180000)
+ return 0;
+
+ if (addr < 0x180000)
+ {
+ len = addr + len - 0x180000;
+ addr = 0x180000;
+ }
+ }
+
+ ctx->events[ctx->counter].type = REG_FIRMWARE_START;
+ ctx->events[ctx->counter].pos = addr;
+ ctx->counter++;
+ ctx->events[ctx->counter].type = REG_FIRMWARE_END;
+ ctx->events[ctx->counter].pos = addr + len;
+ ctx->counter++;
+
+ return 0;
+}
+
+unsigned
+grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
+{
+ struct grub_relocator_firmware_fill_events_ctx ctx = {
+ .events = events,
+ .counter = 0
+ };
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
return 0;
- grub_machine_mmap_iterate (fill);
- return counter;
+ grub_machine_mmap_iterate (grub_relocator_firmware_fill_events_iter, &ctx);
+ return ctx.counter;
}
int
diff --git a/grub-core/lib/libgcrypt/cipher/ChangeLog b/grub-core/lib/libgcrypt/cipher/ChangeLog
index 8924f17..1b3694f 100644
--- a/grub-core/lib/libgcrypt/cipher/ChangeLog
+++ b/grub-core/lib/libgcrypt/cipher/ChangeLog
@@ -1,3 +1,93 @@
+2010-08-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Remove double release of the module.
+ Fixes bug#1263.
+
+2010-06-10 Jeff Johnson <n3npq@mac.com> (wk)
+
+ * ecc.c (ecc_generate_ext): Parse transient-key flag.
+ (generate_key): Add arg TRANSIENT_KEY and use it to set the random
+ level.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-26 Werner Koch <wk@g10code.com>
+
+ * tiger.c (asn): Unfetter the old TIGER from an OID.
+ (TIGER_CONTEXT): Add field VARIANT.
+ (tiger_init): Factor code out to ...
+ (do_init): New.
+ (tiger1_init, tiger2_init): New.
+ (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): New.
+ * md.c (digest_table): Add TIGER1 and TIGER2 variants.
+
+2009-12-11 Werner Koch <wk@g10code.com>
+
+ * sha256.c (Cho, Maj, Sum0, Sum1): Turn macros into inline
+ functions.
+ (transform): Partly unroll to interweave the chain variables
+
+ * sha512.c (ROTR, Ch, Maj, Sum0, Sum1): Turn macros into inline
+ functions.
+ (transform): Partly unroll to interweave the chain variables.
+ Suggested by Christian Grothoff.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (o_flag_munging): New.
+ (tiger.o, tiger.lo): Use it.
+
+ * cipher.c (do_ctr_encrypt): Add arg OUTBUFLEN. Check for
+ suitable value. Add check for valid inputlen. Wipe temporary
+ memory.
+ (do_ctr_decrypt): Likewise.
+ (do_cbc_encrypt, do_cbc_decrypt): Add arg OUTBUFLEN. Check for
+ suitable value. Move check for valid inputlen to here; change
+ returned error from INV_ARG to INV_LENGTH.
+ (do_ecb_encrypt, do_ecb_decrypt): Ditto.
+ (do_cfb_encrypt, do_cfb_decrypt): Ditto.
+ (do_ofb_encrypt, do_ofb_decrypt): Ditto.
+ (cipher_encrypt, cipher_encrypt): Adjust for above changes.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Simplify.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Allow for GCRY_CIPHER_MODE_AESWRAP.
+ (cipher_encrypt, cipher_decrypt): Ditto.
+ (do_aeswrap_encrypt, do_aeswrap_decrypt): New.
+ (struct gcry_cipher_handle): Add field marks.
+ (cipher_setkey, cipher_setiv): Update marks flags.
+ (cipher_reset): Reset marks.
+ (cipher_encrypt, cipher_decrypt): Add new arg OUTBUFLEN.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Pass outbuflen to
+ cipher_encrypt. Replace GPG_ERR_TOO_SHORT by
+ GPG_ERR_BUFFER_TOO_SHORT.
+
+2009-08-21 Werner Koch <wk@g10code.com>
+
+ * dsa.c (dsa_generate_ext): Release retfactors array before
+ setting it to NULL. Reported by Daiko Ueno.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * md.c (md_read): Fix incomplete check for NULL.
+ Reported by Fabian Kail.
+
+2009-03-31 Werner Koch <wk@g10code.com>
+
+ * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not
+ GPG_ERR_PUBKEY_ALGO.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * rsa.c (generate_x931): Do not initialize TBL with automatic
+ variables.
+ * whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c
+ * md4.c, crc.c: Remove memory.h. This is garbage from gnupg.
+ Reported by Dan Fandrich.
+
2009-01-22 Werner Koch <wk@g10code.com>
* ecc.c (compute_keygrip): Remove superfluous const.
@@ -3888,8 +3978,8 @@ Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de)
(digest_algo_to_string): New.
- Copyright 1998,1999,2000,2001,2002,2003,2004,2005,2006
- 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
diff --git a/grub-core/lib/libgcrypt/cipher/Makefile.am b/grub-core/lib/libgcrypt/cipher/Makefile.am
new file mode 100644
index 0000000..4470433
--- /dev/null
+++ b/grub-core/lib/libgcrypt/cipher/Makefile.am
@@ -0,0 +1,82 @@
+# Makefile for cipher modules
+# Copyright (C) 1998, 1999, 2000, 2001, 2002,
+# 2003, 2009 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = Manifest
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+
+
+noinst_LTLIBRARIES = libcipher.la
+
+GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ @GCRYPT_DIGESTS@
+
+libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES)
+libcipher_la_LIBADD = $(GCRYPT_MODULES)
+
+libcipher_la_SOURCES = \
+cipher.c pubkey.c ac.c md.c \
+hmac-tests.c \
+bithelp.h \
+primegen.c \
+hash-common.c hash-common.h \
+rmd.h
+
+EXTRA_libcipher_la_SOURCES = \
+arcfour.c \
+blowfish.c \
+cast5.c \
+crc.c \
+des.c \
+dsa.c \
+elgamal.c \
+ecc.c \
+md4.c \
+md5.c \
+rijndael.c rijndael-tables.h \
+rmd160.c \
+rsa.c \
+seed.c \
+serpent.c \
+sha1.c \
+sha256.c \
+sha512.c \
+tiger.c \
+whirlpool.c \
+twofish.c \
+rfc2268.c \
+camellia.c camellia.h camellia-glue.c
+
+if ENABLE_O_FLAG_MUNGING
+o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g'
+else
+o_flag_munging = cat
+endif
+
+
+# We need to lower the optimization for this module.
+tiger.o: $(srcdir)/tiger.c
+ `echo $(COMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) `
+
+tiger.lo: $(srcdir)/tiger.c
+ `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) `
diff --git a/grub-core/lib/libgcrypt/cipher/Manifest b/grub-core/lib/libgcrypt/cipher/Manifest
new file mode 100644
index 0000000..0cd64f7
--- /dev/null
+++ b/grub-core/lib/libgcrypt/cipher/Manifest
@@ -0,0 +1,73 @@
+# Manifest - checksums of the cipher directory
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# Checksums for all source files in this directory. Format is
+# filename, blanks, base-64 part of an OpenPGP detached signature
+# without the header lines. Blank lines and lines beginning with a
+# hash mark are ignored. A tool to process this file is available by
+# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool
+#
+# The special entry "$names$" holds a signature over all sorted
+# filenames excluding itself.
+
+
+# Algorithm API
+cipher.c iQCVAwUAQDzrVjEAnp832S/7AQIPDgP+OVJ/YNWY5m7c09EBbPAzL/WsGoj6wrBNMmkRlMOqTHeh+OOtjuFHt1f9uhfM2Nzl7sJ5+h4ryZKLEZmQPRMTZTnAqkvGdsrJWJnigUA9QwYdV0ONqC9C63gpuG465gO9TZVOqlQu/FTxSRuTQYUulkaBNG71n8nZEOusBVwV2YA==58xH
+pubkey.c iQCVAwUAP9XQ3jEAnp832S/7AQJ5UgQAyHfEBvPVJ8wTRg8c7ixS2GiVmIgwIo5tvQaiQJTPWASevvYrB+2Z2qa9cATyu50ACjLzbaquGBgPzjJV3dU/qttT1gCqRuN/LCNvXFe5qnIZezejc3RAadFNTw/pOTHq0wxD1Keg66ruei9R36Nba59pEQIWIBXTfubRft2hMYk==E09t
+ac.c iQCVAwUAQDzsOzEAnp832S/7AQJCBQP/WI6EV/dsR4rmha6RVhvkjZo17kQ8z6pIl5J3cXOvqEkIFeD2HYu3HHrWST5l7yXlffhpDkVHkfMih4ruK76q6Fm0dxZ98pO4C/dVtgimlvvcy/wOQjpzsE0fYAe1BYdg81LJ09X33vW5x6C29lunfKROO2tPlV5i8ffeoFvmMF8==j26g
+md.c iQCVAwUAP+NFGjEAnp832S/7AQJs8wP/Qdk0EAKsyr3O1/pmOSN8AG4rPKbd6KDTzvoBPAN4upFwKYY4hWwvy12Q3YU9DmECrzZkRCXHR7mljVQKs6B7CRZJKjFKmOELpcJDtKvu40vTs1bOH4k9iJYZpGgRA83nkQ+ELAcphAbCA+KIpVr2K4mCJAB0FhpC2uOQ50JHAko==BeF6
+primegen.c iQCVAwUAQDzsoDEAnp832S/7AQKYRwP/TqAQBm1rHTnF0HYE05PqXfWlOqa6EosqVpaOcs/OIW6PaqX0xH1UlrukK7jNOjK3xC4o1qNQ1UKzz2dvQaq1bMvNNizeavxAh10SJZc0hIc/ofc83IbjLh8SZVWQ67JxjsUd3DOXmSmhPZ+Pqd7cUIiw8fDoF+I9EZqy3COu1wY==1ebT
+
+# Algorithm implementations
+arcfour.c iQCVAwUAP9XR/TEAnp832S/7AQJcRwP6AlvYEx++fpT4mIYo0xRDqKEQeqMQvbaRhIg2eV74JxItpHa3q5YsYIl+n1yUz5g35JRWWXSWmAZBwO5wLKsHii4kRUhgrKWnSoQZoPpl49L5+N3R58ON3S0ru5lsBiEJEze3xplf2vqwrH9v1QHVD+gU7UTlfNqrIJoOUXN+1O4==Tq+x
+blowfish.c iQCVAwUAP9XTETEAnp832S/7AQJaEgQAgiqqfuO+zQtscgTB0rvOzVymIKjRKjYhFuLjVuc79G4z1RCAffvIn/YM2d7kt+Z/QF7zjcTAOgETCQL1XokpX2zz9HPAMi2tlDY5zsDufTNqj0n4WBL9nM7w6XAvsiwP1B3bqCTv9SjJV4KbxJ58vw1yQE+sqW74R/QIHFvC7mU==wZnX
+cast5.c iQCVAwUAP9XT6DEAnp832S/7AQJ3xgP/ehLjEN3GELGudbqeo91Xd+PqitHrkuBbtRIYX7Udd/fyXLN+h8rMJVyIQX2m+mpxbBxudVU3x8/DNT8B0ZHAwK6qqJmEBLLhEYPgIuF76i9LMrP1KqUPhAwRZ2OppjIIugBQ+rP74aD4eLyd/aKQHNuXML8QGWR6KwQShohXM5I==/BRh
+crc.c iQCVAwUAP7ouejEAnp832S/7AQIgwQQApg5Nm63tH5DQkbN+zPzMO9Ygoj3ukxfFTyTBPYSXYKMiTjEbESegaU40uN8jnz2vprcIQWcgZfzO4+opEJMcI35aPwzEk0vKOp0S/PrBLUY2rJfnDVkX5XgJFZa2Q7LLe826UEBzTVYW924utiCCe8oOaOEWVNpg1mqdknu3M9o==kz5D
+des.c iQCVAwUAQCN2oDEAnp832S/7AQL/jwP6Auoq6nZCDBjpgc9tDzuIRwa9DqyuM3gX94uvgEpUwdHszb2bG43dz03kVmcYxtj1MzXbyCeCZOwox0b2SKmLgxIbrNP6yGbzVdTj6592gDYuf/ZXmc1ZNJ1DDldcPQ0n9fXUipUPwyPaNWo3mSZaNcMKSWWzdK0J6ciG6nk7SWI==9k/t
+dsa.c iQCVAwUAP9XZHDEAnp832S/7AQLBRgP/XrBzTEYx5ccMj1MMb6sg37liEHdIyyy49zjvt6jUqxj4RuwVEN8S6v3u4q/QyJkHAi1E0EkREgENlyHW6PKWhYbcrd0vPIAN15yjnl2yqtrCrJImexUCoqJJewK0E4JOicGbabTil8MZjk+mbhEPnjJBqOkyP1w0i31pEDgE/8M==pC8s
+elgamal.c iQCVAwUAP9XbYzEAnp832S/7AQLXagQA3HrvspZfbTGgmUH0IqLQTJ0exUPxJv5DET2TvoIy62trDmMN6lTAj5P+a7jQ8udcu0w+mR2vXUHcxUpNA2PxLaMwGzNSY4zRDNe9r3SFTDrFm6m4y9Ko2e8XtEA+WF6P/XLpck4Jn7vMEDmVGPwkNd22kXFFE8dBGwG6i5Hk1Mk==oBUs
+md4.c iQCVAwUAP9h50DEAnp832S/7AQJhHgQAzNA/B6MWFDlCtPkIVaW8RpP1Eg0ZNMsy0s7SJkopOCBlu6CwXUOKe+8ppcSxhjYKh4i4uQr/QtfipYlBjzKJGnrafoF/NugXNCOHSTGT11TvK7mCiBuUMVgvZGAlOJImk6eTTfUjRrMfaXM/SWl8bdJ4ZpzdjEyVh89r7I5JrGk==x2UD
+md5.c iQCVAwUAP9h7LzEAnp832S/7AQJUGQP/c0cbf6WZXCzmjufHxiE9FAQBzTsA0WtaNqdFcHl7fhmikGtknlaED8n5a7eYd/C481UQW6Wgq/oZdsvgoPWPhG3fOCy2CFP9cZVXITuMSf0ucyZTFUJNO15fnZ+nDfsUv+JPdv1aSeRinAUtfAcSKfkSyR9BCPZvkx+tgU6cphU==Zv+h
+rijndael.c iQCVAwUAP9h9cTEAnp832S/7AQKF1AP+P2L/tPqDJRDg+/fwbOk8Ts0MNxnvvYEm3gE73TKuLt1S+B2+jkrZcKNvM5VGPnVMJbnS0lmIK04nmedHCOftGTOwhGulZAHHIaKGystT3Jql4iPws/JMgAjE7Fyxh5WZMtB9yEljKBpJ5XNqhrMvvxcHpnyP3+YzIXNwzk34V+c==dJ5k
+rmd160.c iQCVAwUAP9h+bTEAnp832S/7AQK1OgP+PNKF6Nzi6X93easVlksdLqKEsArCAw2QjGWDGyxTnbiJM55qAl9JxR1mn3V+oOL7izLLwTt6EYK9evhzfcxY5N5Mni85RAcsLPsuAfQDEzjI6GUWHtQUKPbM+BaorzfhQjYFSZyvum/dZYJ/WfiwwwhqqIKyVU2ZFSqA38YGC/c==9jdA
+rsa.c iQCVAwUAP9iHIzEAnp832S/7AQKAYwQAuWtnMte54QHN+Hij9t4sGuypXogajOb1vQQwGgS0fKsaBZsuSP2amze4o5diIvsQTsFQ4CzjvqoCVuBDoHM3xkSD8wGDizgvtCamAxkdbF7wmzldKFn8SpJqlVwWQMP6kk1IjXHEuYb4IDWGTbVMhfEu+eOlU8+PSK4IhZqNvt4==/3hp
+serpent.c iQCVAwUAP9h/VzEAnp832S/7AQLyCwP/d1zbmb7l/PriZNa9/Z7mo01XFe5MnAqCfIwhl9GjeaMszcoS37jECNq5nLvrTTFIIJpm3rvBePwiCG4Wwx1I18HCxaP198pcSaR+BLOJ3Aj52EZPrxtqlDKuFr38ZOP5giyUqUYVYGVdrz4kRMNWAZQK53GeJnGhXCnhxojLEgA==ck46
+sha1.c iQCVAwUAP9iATTEAnp832S/7AQKcSwQAwAs/HnNqho3lU1ZUgCPNt5P2/Brm6W21+wWWGKJkSrra/c4NYVKJGDDwlsFE0b9ln1uZt7bHReFkKXK3JnrKTmNVcx/Cy64iCMRNMhaM72Mqy7wWx5yHBAmMBxzFGnNQKbmeY52zeGih5HsNLSibc2pPuOViWo2JPJ5Ci/wIwl8==/wtO
+sha256.c iQCVAwUAP9iAtzEAnp832S/7AQJD2QP/UqvL0hhjG1wEFbGrdkV9tba1sMDXdnnK6X7HdLuRpVAgNiQiFf8JDmntd/dZ2Q71p4Uae2ctqve4WoEijPUZPjACnpuZfx0SEQL0lQBkwxzJp7lz9ujVtwQ2cM/aYexJkXcWgGcloJNLM3JbWPGIJnuYbr/IwJ6RQF9vgj0357o==UWO1
+sha512.c iQCVAwUAP9iBTDEAnp832S/7AQIPBAQA28CJSUQLiW0s2x9u8/OH2eKnxPjA4sZmb50WP7920Lem66P31C3BrOqwfBot4RLhjL+zh/+Uc4s3HPwApZuj9E4BxNMlqLv+Tqk++DAbdaOeYT4jeUt+mlhQQ6mH/RDsy32rZsNsGQ2bUGxazZmfG++PL3JyhawqCy00SUDr/o0==H+0X
+tiger.c iQCVAwUAP9iCfjEAnp832S/7AQKufwP/fryv3MqSOYY+90325DH7X3/CtekxeooN0scGsHX0fxBakWSMecTNrj33KPddLS46gU/S89zIc2N/Bw/7EVIAXVFA3/3Ip+OrFOuIMO4Py1sCdB8o2Y+5ygv8iXLcsXIq1O0av79i9g774V3uaXa2qN9ZnXe0AEhcy8FHJ2i/wro==5XVB
+twofish.c iQCVAwUAP9iD6TEAnp832S/7AQKUnQP/Rq8FaYeHTG7HbZuqAs9pbPitzjDbkdZddmInWR7NmevBkKvhsJALjVooc0KGQfo2lAAmy3Xi/4QQN8VPn51DVjDIgf7x+DQh/9TFJHMccxI9asUgi4+TNnmMqLU1k3N8S2PjyZ1sjeC8B79fKPpwCzj72WkqPkzZw3l2jArr+dU==NdJT
+rfc2268.c iQCVAwUAQCN+3jEAnp832S/7AQLv1gQA1hJh29hAjKi4uLSGxXvJ6cyYmPdmevdKrbLnuHZWtHe4xvCgy/nTdEojEpxgLp/hL/ogasuWRC1W16Wiz9ryxf7YR0uhZWayO/bQNagpfU5MIkJTLuKqqgpwYumCSQfOugXVAqcgEzj+13eeyJaFVrzwrNa67sh84nmbjOjNjvE==0zBq
+
+# Random number related
+random.c iQCVAwUAP7nsITEAnp832S/7AQK4SAQAtvfUgrtGOQ2PlxGMla0qJLPHjJacMwgq0ecusiI79elPdDsFfCCk6dK1Ug2kFbNm22nCGHNcUquqbX7noi7ZVQnmPBQXzyLNZd7GmrawRZfdlRerTUDBpSnR8V8ui/5+YYp627E7kKGC0hPSgqXFql6oBMIfno0LZwFJTjIevRY==L419
+random.h iQCVAwUAP7ovKDEAnp832S/7AQJ3bQQAjnPebnyTC7sphAv2I7uIz+yPgw1ZfbVhLv+OiWDlO9ish+fRyyMpy+HELBOgZjJdgRegqhlZC6qyns5arM/VglYi+PzvdLO3hIqHE/YFfpIFPz8wBrcmlqrYyd3CsGqcYsfjocXNttCBLeSWmoJ09ltKQH8yzJf3oAgN6X1yuc4==eNoU
+rand-internal.h iQCVAwUAP7ouvDEAnp832S/7AQLYnAQAhdI7ERoJVCkV8GiV7MjaUxv1WIL7iZ+jIOvVhv4fNyhCGCGoEtTjkyput/lj7Nsh3FXEqRhypGGrCLf47x/gua5n+BwffogxVyUDqiOyyGhNTPpe3fQcNBvbPCtco8yMK4GJO5G3BqzlPyN+BMeogLymyV6Sm1mvh5LZDyAFbfQ==tZSE
+rndlinux.c iQCVAwUAP9iPYTEAnp832S/7AQL6/AP/ZDrbOkVuB9qJ7sKeX1MImZEsz3mi0xPovJzaBtBU7a0idcUKrWYOvQFWRlLUeq0iCT6+h2l5bniP7q7hepzlKa+VPY9VWaQthqeJm2l5LN6QQ5PyMfBq04QuBncw9BJnCGmEyTLt3RxIXBAPdxmiVxtcRIFUqCBtQvoUXGLvemw==t37k
+rndegd.c iQCVAwUAP9iPRDEAnp832S/7AQImBQP/WHKg+hKXcm1pQvilzML0jZpwK5PAMM4uBnnPJNIXWOYBO6I/Xg9d/tPLg8NlmmtyQCo2Eu0ybDSt+8mu+dWveAys+0LTi0MIqeP9BMzCKz8dnWH6+S8huLXwTF3m0IrqM0JLb6b71GK9SOq6sWQ22yW5vf61hXP8kH9dhIaoMZs==FaHV
+rndunix.c iQCVAwUAP9iQlzEAnp832S/7AQL/KgQA29GnvcD4Xb5qjDMBgW9THEE4+4lfex/6k+Fh0IT61OLJsWVLJ7bJpRntburw4uQm4Tf7CO8vaiDFDYhKKrzXeOF1fmdpcL8hA+fNp9I/MUOc4e9kN9+YJ9wikVa0SZj1OBfhzgcFLd1xOtulkr3ii52HLF9vhrxzkgVwvD10Bi8==2cML
+rndw32.c iQCVAwUAP9iRKDEAnp832S/7AQIuaAQA3AJr3WqnxNDsWCIdvehf8Suotthj+laX8nJsvDfFhXPKcXDpsg0wTTXSnnKgyED53+uYiMDnVRsxeWAyhKwvx1MjjlaSMMjzbH6isWTH8FaWpLgrxEkXoPeNqYf5FXpdUkcUxGX2RkQeuX/cIfiHLNE9CV0usaF2jysjBX2iERY==EEnO
+
+# Helper
+bithelp.h iQCVAwUAP7ouPTEAnp832S/7AQKXggQAqjcgvihIF3WclOgw1JV2rbARw4ISIDRMFqdaNCqBRx6BwEz3UGsEIlz6+iR1sS/reqN61WvtjLb+D0+tujAkGrgQJhFLG85WtG2tB5UVoI3am1fpkwiRm+bR4rv0rGk0BYk81bC7+l4KrK9o5lVp4lCsrorlUKsd48lNmBHyAXM==mDDN
+rmd.h iQCVAwUAP7oumjEAnp832S/7AQJiJQP/V4bJwjZaYndJzV+KRnIDbl1koHuw+ZK5heMYVu8Qk4ylqv//BGyeRa3jZCcfPHI35q6HilCs2VBm8hiBMjHSqY/VPn2ZQ0yg/lt6qEvl7YjsLmyMICvjG+ncszHoq9pRvnF3vTnM18sPIioXLk8fskuM0XOCNBs0ARBAQjY9UGI==olUN
+
+# Configuration
+Makefile.am iQCVAwUAQCN33TEAnp832S/7AQKFJAQAz7BDkC814q+QiuE/jnutJHR5qlgbrm3ikGbQwdRzYUscst4bCCWy3uKL/sIPGLg+JQXtF5FnsQy3s4D9BOYhp72cA9ktYK65hhi4pNm/JQ0lXkZMNfk8Go5lNzKezlWwHvkMwRXR0Fep0wPdyeaKW5BfaW2ABvgep6Bp+hHEbyg==zSyi
+$names$ iQCVAwUAQCN3EDEAnp832S/7AQJXLAP8DvHTpm5DkTF35EmzeKpi9ie59AZcZanD19ir/e/7+PaQxr2riuLHDGwFKTju+dcvvBsqrygXOC378GXVWzIF2OZwS4EdDcJ+pgojo9UpsqpKsJHouY4Ugx5cQialxba462kUn8hcihSBnMyc4LzbJ5WQ4puQuqy544d2x94+2ms==G4Ls
diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/grub-core/lib/libgcrypt/cipher/ac.c
index ee9498b..14569cc 100644
--- a/grub-core/lib/libgcrypt/cipher/ac.c
+++ b/grub-core/lib/libgcrypt/cipher/ac.c
@@ -2499,7 +2499,7 @@ typedef enum dencode_action
dencode_action_t;
/* Encode or decode a message according to the the encoding method
- METHOD; ACTION specifies wether the message that is contained in
+ METHOD; ACTION specifies whether the message that is contained in
BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
The resulting message will be stored in a newly allocated buffer in
BUFFER_OUT and BUFFER_OUT_N. */
diff --git a/grub-core/lib/libgcrypt/cipher/cipher.c b/grub-core/lib/libgcrypt/cipher/cipher.c
index 2c33ee9..03455e1 100644
--- a/grub-core/lib/libgcrypt/cipher/cipher.c
+++ b/grub-core/lib/libgcrypt/cipher/cipher.c
@@ -1,6 +1,6 @@
/* cipher.c - cipher dispatcher
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- * 2005, 2007, 2008 Free Software Foundation, Inc.
+ * 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -118,7 +118,7 @@ static gcry_module_t ciphers_registered;
/* This is the lock protecting CIPHERS_REGISTERED. */
static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER;
-/* Flag to check wether the default ciphers have already been
+/* Flag to check whether the default ciphers have already been
registered. */
static int default_ciphers_registered;
@@ -192,6 +192,11 @@ struct gcry_cipher_handle
int mode;
unsigned int flags;
+ struct {
+ unsigned int key:1; /* Set to 1 if a key has been set. */
+ unsigned int iv:1; /* Set to 1 if a IV has been set. */
+ } marks;
+
/* The initialization vector. To help code optimization we make
sure that it is aligned on an unsigned long and u32 boundary. */
union {
@@ -681,7 +686,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
REGISTER_DEFAULT_CIPHERS;
- /* Fetch the according module and check wether the cipher is marked
+ /* Fetch the according module and check whether the cipher is marked
available for use. */
ath_mutex_lock (&ciphers_registered_lock);
module = _gcry_module_lookup_id (ciphers_registered, algo);
@@ -693,7 +698,6 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
{
/* Not available for use. */
err = GPG_ERR_CIPHER_ALGO;
- _gcry_module_release (module);
}
else
{
@@ -724,6 +728,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
case GCRY_CIPHER_MODE_CFB:
case GCRY_CIPHER_MODE_OFB:
case GCRY_CIPHER_MODE_CTR:
+ case GCRY_CIPHER_MODE_AESWRAP:
if ((cipher->encrypt == dummy_encrypt_block)
|| (cipher->decrypt == dummy_decrypt_block))
err = GPG_ERR_INV_CIPHER_MODE;
@@ -882,7 +887,10 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned int keylen)
memcpy ((void *) ((char *) &c->context.c + c->cipher->contextsize),
(void *) &c->context.c,
c->cipher->contextsize);
+ c->marks.key = 1;
}
+ else
+ c->marks.key = 0;
return gcry_error (ret);
}
@@ -905,7 +913,10 @@ cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
if (ivlen > c->cipher->blocksize)
ivlen = c->cipher->blocksize;
memcpy (c->u_iv.iv, iv, ivlen);
+ c->marks.iv = 1;
}
+ else
+ c->marks.iv = 0;
c->unused = 0;
}
@@ -918,54 +929,85 @@ cipher_reset (gcry_cipher_hd_t c)
memcpy (&c->context.c,
(char *) &c->context.c + c->cipher->contextsize,
c->cipher->contextsize);
+ memset (&c->marks, 0, sizeof c->marks);
memset (c->u_iv.iv, 0, c->cipher->blocksize);
memset (c->lastiv, 0, c->cipher->blocksize);
memset (c->ctr, 0, c->cipher->blocksize);
}
-static void
-do_ecb_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
- unsigned int nblocks )
+
+static gcry_err_code_t
+do_ecb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
- unsigned int n;
+ unsigned int blocksize = c->cipher->blocksize;
+ unsigned int n, nblocks;
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if ((inbuflen % blocksize))
+ return GPG_ERR_INV_LENGTH;
+
+ nblocks = inbuflen / c->cipher->blocksize;
+
for (n=0; n < nblocks; n++ )
{
- c->cipher->encrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
- inbuf += c->cipher->blocksize;
- outbuf += c->cipher->blocksize;
+ c->cipher->encrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf);
+ inbuf += blocksize;
+ outbuf += blocksize;
}
+ return 0;
}
-static void
-do_ecb_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
- unsigned int nblocks )
+static gcry_err_code_t
+do_ecb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
- unsigned int n;
+ unsigned int blocksize = c->cipher->blocksize;
+ unsigned int n, nblocks;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if ((inbuflen % blocksize))
+ return GPG_ERR_INV_LENGTH;
+ nblocks = inbuflen / c->cipher->blocksize;
for (n=0; n < nblocks; n++ )
{
- c->cipher->decrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
- inbuf += c->cipher->blocksize;
- outbuf += c->cipher->blocksize;
+ c->cipher->decrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf );
+ inbuf += blocksize;
+ outbuf += blocksize;
}
+
+ return 0;
}
-static void
-do_cbc_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
- const unsigned char *inbuf, unsigned int nbytes )
+static gcry_err_code_t
+do_cbc_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
unsigned int n;
unsigned char *ivp;
int i;
size_t blocksize = c->cipher->blocksize;
- unsigned nblocks = nbytes / blocksize;
+ unsigned nblocks = inbuflen / blocksize;
+
+ if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen))
+ return GPG_ERR_BUFFER_TOO_SHORT;
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
+ if ((inbuflen % c->cipher->blocksize)
+ && !(inbuflen > c->cipher->blocksize
+ && (c->flags & GCRY_CIPHER_CBC_CTS)))
+ return GPG_ERR_INV_LENGTH;
+
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
{
- if ((nbytes % blocksize) == 0)
+ if ((inbuflen % blocksize) == 0)
nblocks--;
}
@@ -991,17 +1033,17 @@ do_cbc_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
}
}
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
{
/* We have to be careful here, since outbuf might be equal to
inbuf. */
int restbytes;
unsigned char b;
- if ((nbytes % blocksize) == 0)
+ if ((inbuflen % blocksize) == 0)
restbytes = blocksize;
else
- restbytes = nbytes % blocksize;
+ restbytes = inbuflen % blocksize;
outbuf -= blocksize;
for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
@@ -1016,23 +1058,34 @@ do_cbc_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
c->cipher->encrypt (&c->context.c, outbuf, outbuf);
memcpy (c->u_iv.iv, outbuf, blocksize);
}
+
+ return 0;
}
-static void
-do_cbc_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
- const unsigned char *inbuf, unsigned int nbytes)
+static gcry_err_code_t
+do_cbc_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
unsigned int n;
unsigned char *ivp;
int i;
size_t blocksize = c->cipher->blocksize;
- unsigned int nblocks = nbytes / blocksize;
+ unsigned int nblocks = inbuflen / blocksize;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
+ if ((inbuflen % c->cipher->blocksize)
+ && !(inbuflen > c->cipher->blocksize
+ && (c->flags & GCRY_CIPHER_CBC_CTS)))
+ return GPG_ERR_INV_LENGTH;
+
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
{
nblocks--;
- if ((nbytes % blocksize) == 0)
+ if ((inbuflen % blocksize) == 0)
nblocks--;
memcpy (c->lastiv, c->u_iv.iv, blocksize);
}
@@ -1060,14 +1113,14 @@ do_cbc_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
}
}
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
{
int restbytes;
- if ((nbytes % blocksize) == 0)
+ if ((inbuflen % blocksize) == 0)
restbytes = blocksize;
else
- restbytes = nbytes % blocksize;
+ restbytes = inbuflen % blocksize;
memcpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */
memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
@@ -1084,32 +1137,38 @@ do_cbc_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
outbuf[i] ^= *ivp++;
/* c->lastiv is now really lastlastiv, does this matter? */
}
+
+ return 0;
}
-static void
-do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
- const unsigned char *inbuf, unsigned int nbytes )
+static gcry_err_code_t
+do_cfb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
unsigned char *ivp;
size_t blocksize = c->cipher->blocksize;
size_t blocksize_x_2 = blocksize + blocksize;
- if ( nbytes <= c->unused )
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ( inbuflen <= c->unused )
{
/* Short enough to be encoded by the remaining XOR mask. */
/* XOR the input with the IV and store input into IV. */
for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
- nbytes;
- nbytes--, c->unused-- )
+ inbuflen;
+ inbuflen--, c->unused-- )
*outbuf++ = (*ivp++ ^= *inbuf++);
- return;
+ return 0;
}
if ( c->unused )
{
/* XOR the input with the IV and store input into IV */
- nbytes -= c->unused;
+ inbuflen -= c->unused;
for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
*outbuf++ = (*ivp++ ^= *inbuf++);
}
@@ -1117,17 +1176,17 @@ do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
/* Now we can process complete blocks. We use a loop as long as we
have at least 2 blocks and use conditions for the rest. This
also allows to use a bulk encryption function if available. */
- if (nbytes >= blocksize_x_2 && c->bulk.cfb_enc)
+ if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc)
{
- unsigned int nblocks = nbytes / blocksize;
+ unsigned int nblocks = inbuflen / blocksize;
c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
outbuf += nblocks * blocksize;
inbuf += nblocks * blocksize;
- nbytes -= nblocks * blocksize;
+ inbuflen -= nblocks * blocksize;
}
else
{
- while ( nbytes >= blocksize_x_2 )
+ while ( inbuflen >= blocksize_x_2 )
{
int i;
/* Encrypt the IV. */
@@ -1135,11 +1194,11 @@ do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
/* XOR the input with the IV and store input into IV. */
for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
*outbuf++ = (*ivp++ ^= *inbuf++);
- nbytes -= blocksize;
+ inbuflen -= blocksize;
}
}
- if ( nbytes >= blocksize )
+ if ( inbuflen >= blocksize )
{
int i;
/* Save the current IV and then encrypt the IV. */
@@ -1148,25 +1207,27 @@ do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
/* XOR the input with the IV and store input into IV */
for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
*outbuf++ = (*ivp++ ^= *inbuf++);
- nbytes -= blocksize;
+ inbuflen -= blocksize;
}
- if ( nbytes )
+ if ( inbuflen )
{
/* Save the current IV and then encrypt the IV. */
memcpy( c->lastiv, c->u_iv.iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
c->unused = blocksize;
/* Apply the XOR. */
- c->unused -= nbytes;
- for(ivp=c->u_iv.iv; nbytes; nbytes-- )
+ c->unused -= inbuflen;
+ for(ivp=c->u_iv.iv; inbuflen; inbuflen-- )
*outbuf++ = (*ivp++ ^= *inbuf++);
}
+ return 0;
}
-static void
-do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
- const unsigned char *inbuf, unsigned int nbytes )
+static gcry_err_code_t
+do_cfb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
unsigned char *ivp;
unsigned long temp;
@@ -1174,25 +1235,28 @@ do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
size_t blocksize = c->cipher->blocksize;
size_t blocksize_x_2 = blocksize + blocksize;
- if (nbytes <= c->unused)
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if (inbuflen <= c->unused)
{
/* Short enough to be encoded by the remaining XOR mask. */
/* XOR the input with the IV and store input into IV. */
for (ivp=c->u_iv.iv+blocksize - c->unused;
- nbytes;
- nbytes--, c->unused--)
+ inbuflen;
+ inbuflen--, c->unused--)
{
temp = *inbuf++;
*outbuf++ = *ivp ^ temp;
*ivp++ = temp;
}
- return;
+ return 0;
}
if (c->unused)
{
/* XOR the input with the IV and store input into IV. */
- nbytes -= c->unused;
+ inbuflen -= c->unused;
for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
{
temp = *inbuf++;
@@ -1204,17 +1268,17 @@ do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
/* Now we can process complete blocks. We use a loop as long as we
have at least 2 blocks and use conditions for the rest. This
also allows to use a bulk encryption function if available. */
- if (nbytes >= blocksize_x_2 && c->bulk.cfb_dec)
+ if (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec)
{
- unsigned int nblocks = nbytes / blocksize;
+ unsigned int nblocks = inbuflen / blocksize;
c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
outbuf += nblocks * blocksize;
inbuf += nblocks * blocksize;
- nbytes -= nblocks * blocksize;
+ inbuflen -= nblocks * blocksize;
}
else
{
- while (nbytes >= blocksize_x_2 )
+ while (inbuflen >= blocksize_x_2 )
{
/* Encrypt the IV. */
c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
@@ -1225,11 +1289,11 @@ do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
*outbuf++ = *ivp ^ temp;
*ivp++ = temp;
}
- nbytes -= blocksize;
+ inbuflen -= blocksize;
}
}
- if (nbytes >= blocksize )
+ if (inbuflen >= blocksize )
{
/* Save the current IV and then encrypt the IV. */
memcpy ( c->lastiv, c->u_iv.iv, blocksize);
@@ -1241,54 +1305,59 @@ do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf,
*outbuf++ = *ivp ^ temp;
*ivp++ = temp;
}
- nbytes -= blocksize;
+ inbuflen -= blocksize;
}
- if (nbytes)
+ if (inbuflen)
{
/* Save the current IV and then encrypt the IV. */
memcpy ( c->lastiv, c->u_iv.iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
c->unused = blocksize;
/* Apply the XOR. */
- c->unused -= nbytes;
- for (ivp=c->u_iv.iv; nbytes; nbytes-- )
+ c->unused -= inbuflen;
+ for (ivp=c->u_iv.iv; inbuflen; inbuflen-- )
{
temp = *inbuf++;
*outbuf++ = *ivp ^ temp;
*ivp++ = temp;
}
}
+ return 0;
}
-static void
-do_ofb_encrypt( gcry_cipher_hd_t c,
- byte *outbuf, const byte *inbuf, unsigned nbytes )
+static gcry_err_code_t
+do_ofb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
- byte *ivp;
+ unsigned char *ivp;
size_t blocksize = c->cipher->blocksize;
- if ( nbytes <= c->unused )
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ( inbuflen <= c->unused )
{
/* Short enough to be encoded by the remaining XOR mask. */
/* XOR the input with the IV */
for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
- nbytes;
- nbytes--, c->unused-- )
+ inbuflen;
+ inbuflen--, c->unused-- )
*outbuf++ = (*ivp++ ^ *inbuf++);
- return;
+ return 0;
}
if( c->unused )
{
- nbytes -= c->unused;
+ inbuflen -= c->unused;
for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
*outbuf++ = (*ivp++ ^ *inbuf++);
}
/* Now we can process complete blocks. */
- while ( nbytes >= blocksize )
+ while ( inbuflen >= blocksize )
{
int i;
/* Encrypt the IV (and save the current one). */
@@ -1297,43 +1366,48 @@ do_ofb_encrypt( gcry_cipher_hd_t c,
for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
*outbuf++ = (*ivp++ ^ *inbuf++);
- nbytes -= blocksize;
+ inbuflen -= blocksize;
}
- if ( nbytes )
+ if ( inbuflen )
{ /* process the remaining bytes */
memcpy( c->lastiv, c->u_iv.iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
c->unused = blocksize;
- c->unused -= nbytes;
- for(ivp=c->u_iv.iv; nbytes; nbytes-- )
+ c->unused -= inbuflen;
+ for(ivp=c->u_iv.iv; inbuflen; inbuflen-- )
*outbuf++ = (*ivp++ ^ *inbuf++);
}
+ return 0;
}
-static void
-do_ofb_decrypt( gcry_cipher_hd_t c,
- byte *outbuf, const byte *inbuf, unsigned int nbytes )
+static gcry_err_code_t
+do_ofb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
- byte *ivp;
+ unsigned char *ivp;
size_t blocksize = c->cipher->blocksize;
- if( nbytes <= c->unused )
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if( inbuflen <= c->unused )
{
/* Short enough to be encoded by the remaining XOR mask. */
- for (ivp=c->u_iv.iv+blocksize - c->unused; nbytes; nbytes--,c->unused--)
+ for (ivp=c->u_iv.iv+blocksize - c->unused; inbuflen; inbuflen--,c->unused--)
*outbuf++ = *ivp++ ^ *inbuf++;
- return;
+ return 0;
}
if ( c->unused )
{
- nbytes -= c->unused;
+ inbuflen -= c->unused;
for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
*outbuf++ = *ivp++ ^ *inbuf++;
}
/* Now we can process complete blocks. */
- while ( nbytes >= blocksize )
+ while ( inbuflen >= blocksize )
{
int i;
/* Encrypt the IV (and save the current one). */
@@ -1341,36 +1415,45 @@ do_ofb_decrypt( gcry_cipher_hd_t c,
c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
*outbuf++ = *ivp++ ^ *inbuf++;
- nbytes -= blocksize;
+ inbuflen -= blocksize;
}
- if ( nbytes )
+ if ( inbuflen )
{ /* Process the remaining bytes. */
/* Encrypt the IV (and save the current one). */
memcpy( c->lastiv, c->u_iv.iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
c->unused = blocksize;
- c->unused -= nbytes;
- for (ivp=c->u_iv.iv; nbytes; nbytes-- )
+ c->unused -= inbuflen;
+ for (ivp=c->u_iv.iv; inbuflen; inbuflen-- )
*outbuf++ = *ivp++ ^ *inbuf++;
}
+ return 0;
}
-static void
-do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
- unsigned int nbytes )
+static gcry_err_code_t
+do_ctr_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
unsigned int n;
- byte tmp[MAX_BLOCKSIZE];
+ unsigned char tmp[MAX_BLOCKSIZE];
int i;
+ unsigned int blocksize = c->cipher->blocksize;
- for(n=0; n < nbytes; n++)
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ((inbuflen % blocksize))
+ return GPG_ERR_INV_LENGTH;
+
+ for (n=0; n < inbuflen; n++)
{
- if ((n % c->cipher->blocksize) == 0)
+ if ((n % blocksize) == 0)
{
c->cipher->encrypt (&c->context.c, tmp, c->ctr);
- for (i = c->cipher->blocksize; i > 0; i--)
+ for (i = blocksize; i > 0; i--)
{
c->ctr[i-1]++;
if (c->ctr[i-1] != 0)
@@ -1378,76 +1461,252 @@ do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
}
}
- /* XOR input with encrypted counter and store in output. */
- outbuf[n] = inbuf[n] ^ tmp[n % c->cipher->blocksize];
+ /* XOR input with encrypted counter and store in output. */
+ outbuf[n] = inbuf[n] ^ tmp[n % blocksize];
}
+
+ wipememory (tmp, sizeof tmp);
+ return 0;
}
-static void
-do_ctr_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
- unsigned int nbytes )
+static gcry_err_code_t
+do_ctr_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
{
- do_ctr_encrypt (c, outbuf, inbuf, nbytes);
+ return do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+}
+
+
+/* Perform the AES-Wrap algorithm as specified by RFC3394. We
+ implement this as a mode usable with any cipher algorithm of
+ blocksize 128. */
+static gcry_err_code_t
+do_aeswrap_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
+ const byte *inbuf, unsigned int inbuflen )
+{
+ int j, x;
+ unsigned int n, i;
+ unsigned char *r, *a, *b;
+ unsigned char t[8];
+
+#if MAX_BLOCKSIZE < 8
+#error Invalid block size
+#endif
+ /* We require a cipher with a 128 bit block length. */
+ if (c->cipher->blocksize != 16)
+ return GPG_ERR_INV_LENGTH;
+
+ /* The output buffer must be able to hold the input data plus one
+ additional block. */
+ if (outbuflen < inbuflen + 8)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ /* Input data must be multiple of 64 bits. */
+ if (inbuflen % 8)
+ return GPG_ERR_INV_ARG;
+
+ n = inbuflen / 8;
+
+ /* We need at least two 64 bit blocks. */
+ if (n < 2)
+ return GPG_ERR_INV_ARG;
+
+ r = outbuf;
+ a = outbuf; /* We store A directly in OUTBUF. */
+ b = c->ctr; /* B is also used to concatenate stuff. */
+
+ /* If an IV has been set we use that IV as the Alternative Initial
+ Value; if it has not been set we use the standard value. */
+ if (c->marks.iv)
+ memcpy (a, c->u_iv.iv, 8);
+ else
+ memset (a, 0xa6, 8);
+
+ /* Copy the inbuf to the outbuf. */
+ memmove (r+8, inbuf, inbuflen);
+
+ memset (t, 0, sizeof t); /* t := 0. */
+
+ for (j = 0; j <= 5; j++)
+ {
+ for (i = 1; i <= n; i++)
+ {
+ /* B := AES_k( A | R[i] ) */
+ memcpy (b, a, 8);
+ memcpy (b+8, r+i*8, 8);
+ c->cipher->encrypt (&c->context.c, b, b);
+ /* t := t + 1 */
+ for (x = 7; x >= 0; x--)
+ {
+ t[x]++;
+ if (t[x])
+ break;
+ }
+ /* A := MSB_64(B) ^ t */
+ for (x=0; x < 8; x++)
+ a[x] = b[x] ^ t[x];
+ /* R[i] := LSB_64(B) */
+ memcpy (r+i*8, b+8, 8);
+ }
+ }
+
+ return 0;
+}
+
+/* Perform the AES-Unwrap algorithm as specified by RFC3394. We
+ implement this as a mode usable with any cipher algorithm of
+ blocksize 128. */
+static gcry_err_code_t
+do_aeswrap_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
+ const byte *inbuf, unsigned int inbuflen)
+{
+ int j, x;
+ unsigned int n, i;
+ unsigned char *r, *a, *b;
+ unsigned char t[8];
+
+#if MAX_BLOCKSIZE < 8
+#error Invalid block size
+#endif
+ /* We require a cipher with a 128 bit block length. */
+ if (c->cipher->blocksize != 16)
+ return GPG_ERR_INV_LENGTH;
+
+ /* The output buffer must be able to hold the input data minus one
+ additional block. Fixme: The caller has more restrictive checks
+ - we may want to fix them for this mode. */
+ if (outbuflen + 8 < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ /* Input data must be multiple of 64 bits. */
+ if (inbuflen % 8)
+ return GPG_ERR_INV_ARG;
+
+ n = inbuflen / 8;
+
+ /* We need at least three 64 bit blocks. */
+ if (n < 3)
+ return GPG_ERR_INV_ARG;
+
+ r = outbuf;
+ a = c->lastiv; /* We use c->LASTIV as buffer for A. */
+ b = c->ctr; /* B is also used to concatenate stuff. */
+
+ /* Copy the inbuf to the outbuf and save A. */
+ memcpy (a, inbuf, 8);
+ memmove (r, inbuf+8, inbuflen-8);
+ n--; /* Reduce to actual number of data blocks. */
+
+ /* t := 6 * n */
+ i = n * 6; /* The range is valid because: n = inbuflen / 8 - 1. */
+ for (x=0; x < 8 && x < sizeof (i); x++)
+ t[7-x] = i >> (8*x);
+ for (; x < 8; x++)
+ t[7-x] = 0;
+
+ for (j = 5; j >= 0; j--)
+ {
+ for (i = n; i >= 1; i--)
+ {
+ /* B := AES_k^1( (A ^ t)| R[i] ) */
+ for (x = 0; x < 8; x++)
+ b[x] = a[x] ^ t[x];
+ memcpy (b+8, r+(i-1)*8, 8);
+ c->cipher->decrypt (&c->context.c, b, b);
+ /* t := t - 1 */
+ for (x = 7; x >= 0; x--)
+ {
+ t[x]--;
+ if (t[x] != 0xff)
+ break;
+ }
+ /* A := MSB_64(B) */
+ memcpy (a, b, 8);
+ /* R[i] := LSB_64(B) */
+ memcpy (r+(i-1)*8, b+8, 8);
+ }
+ }
+
+ /* If an IV has been set we compare against this Alternative Initial
+ Value; if it has not been set we compare against the standard IV. */
+ if (c->marks.iv)
+ j = memcmp (a, c->u_iv.iv, 8);
+ else
+ {
+ for (j=0, x=0; x < 8; x++)
+ if (a[x] != 0xa6)
+ {
+ j=1;
+ break;
+ }
+ }
+ return j? GPG_ERR_CHECKSUM : 0;
}
/****************
* Encrypt INBUF to OUTBUF with the mode selected at open.
* inbuf and outbuf may overlap or be the same.
- * Depending on the mode some contraints apply to NBYTES.
+ * Depending on the mode some constraints apply to INBUFLEN.
*/
static gcry_err_code_t
-cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf,
- const byte *inbuf, unsigned int nbytes)
+cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
+ const byte *inbuf, unsigned int inbuflen)
{
- gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+ gcry_err_code_t rc;
- switch( c->mode ) {
- case GCRY_CIPHER_MODE_ECB:
- if (!(nbytes%c->cipher->blocksize))
- do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
- else
- rc = GPG_ERR_INV_ARG;
- break;
- case GCRY_CIPHER_MODE_CBC:
- if (!(nbytes%c->cipher->blocksize)
- || (nbytes > c->cipher->blocksize
- && (c->flags & GCRY_CIPHER_CBC_CTS)))
- do_cbc_encrypt(c, outbuf, inbuf, nbytes );
- else
- rc = GPG_ERR_INV_ARG;
- break;
- case GCRY_CIPHER_MODE_CFB:
- do_cfb_encrypt(c, outbuf, inbuf, nbytes );
- break;
- case GCRY_CIPHER_MODE_OFB:
- do_ofb_encrypt(c, outbuf, inbuf, nbytes );
- break;
- case GCRY_CIPHER_MODE_CTR:
- do_ctr_encrypt(c, outbuf, inbuf, nbytes );
- break;
- case GCRY_CIPHER_MODE_STREAM:
- c->cipher->stencrypt ( &c->context.c,
- outbuf, (byte*)/*arggg*/inbuf, nbytes );
- break;
- case GCRY_CIPHER_MODE_NONE:
- if (fips_mode () || !_gcry_get_debug_flag (0))
- {
- fips_signal_error ("cipher mode NONE used");
- rc = GPG_ERR_INV_CIPHER_MODE;
- }
- else
- {
- if ( inbuf != outbuf )
- memmove (outbuf, inbuf, nbytes);
- }
- break;
- default:
- log_fatal("cipher_encrypt: invalid mode %d\n", c->mode );
- rc = GPG_ERR_INV_CIPHER_MODE;
- break;
+ switch (c->mode)
+ {
+ case GCRY_CIPHER_MODE_ECB:
+ rc = do_ecb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CBC:
+ rc = do_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CFB:
+ rc = do_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_OFB:
+ rc = do_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CTR:
+ rc = do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_AESWRAP:
+ rc = do_aeswrap_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_STREAM:
+ c->cipher->stencrypt (&c->context.c,
+ outbuf, (byte*)/*arggg*/inbuf, inbuflen);
+ rc = 0;
+ break;
+
+ case GCRY_CIPHER_MODE_NONE:
+ if (fips_mode () || !_gcry_get_debug_flag (0))
+ {
+ fips_signal_error ("cipher mode NONE used");
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+ else
+ {
+ if (inbuf != outbuf)
+ memmove (outbuf, inbuf, inbuflen);
+ rc = 0;
+ }
+ break;
+
+ default:
+ log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode );
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
}
- return rc;
+
+ return rc;
}
@@ -1461,29 +1720,15 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
{
gcry_err_code_t err;
- if (!in)
- {
- /* Caller requested in-place encryption. */
- /* Actually cipher_encrypt() does not need to know about it, but
- * we may change it in the future to get better performance. */
- err = cipher_encrypt (h, out, out, outsize);
- }
- else if (outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ?
- h->cipher->blocksize : inlen))
- err = GPG_ERR_TOO_SHORT;
- else if ((h->mode == GCRY_CIPHER_MODE_ECB
- || (h->mode == GCRY_CIPHER_MODE_CBC
- && (! ((h->flags & GCRY_CIPHER_CBC_CTS)
- && (inlen > h->cipher->blocksize)))))
- && (inlen % h->cipher->blocksize))
- err = GPG_ERR_INV_ARG;
+ if (!in) /* Caller requested in-place encryption. */
+ err = cipher_encrypt (h, out, outsize, out, outsize);
else
- err = cipher_encrypt (h, out, in, inlen);
+ err = cipher_encrypt (h, out, outsize, in, inlen);
+ /* Failsafe: Make sure that the plaintext will never make it into
+ OUT if the encryption returned an error. */
if (err && out)
- memset (out, 0x42, outsize); /* Failsafe: Make sure that the
- plaintext will never make it into
- OUT. */
+ memset (out, 0x42, outsize);
return gcry_error (err);
}
@@ -1493,60 +1738,67 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
/****************
* Decrypt INBUF to OUTBUF with the mode selected at open.
* inbuf and outbuf may overlap or be the same.
- * Depending on the mode some some contraints apply to NBYTES.
+ * Depending on the mode some some contraints apply to INBUFLEN.
*/
static gcry_err_code_t
-cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
- unsigned int nbytes)
+cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
+ const byte *inbuf, unsigned int inbuflen)
{
- gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+ gcry_err_code_t rc;
- switch( c->mode ) {
- case GCRY_CIPHER_MODE_ECB:
- if (!(nbytes%c->cipher->blocksize))
- do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
- else
- rc = GPG_ERR_INV_ARG;
- break;
- case GCRY_CIPHER_MODE_CBC:
- if (!(nbytes%c->cipher->blocksize)
- || (nbytes > c->cipher->blocksize
- && (c->flags & GCRY_CIPHER_CBC_CTS)))
- do_cbc_decrypt(c, outbuf, inbuf, nbytes );
- else
- rc = GPG_ERR_INV_ARG;
- break;
- case GCRY_CIPHER_MODE_CFB:
- do_cfb_decrypt(c, outbuf, inbuf, nbytes );
- break;
- case GCRY_CIPHER_MODE_OFB:
- do_ofb_decrypt(c, outbuf, inbuf, nbytes );
- break;
- case GCRY_CIPHER_MODE_CTR:
- do_ctr_decrypt(c, outbuf, inbuf, nbytes );
- break;
- case GCRY_CIPHER_MODE_STREAM:
- c->cipher->stdecrypt ( &c->context.c,
- outbuf, (byte*)/*arggg*/inbuf, nbytes );
- break;
- case GCRY_CIPHER_MODE_NONE:
- if (fips_mode () || !_gcry_get_debug_flag (0))
- {
- fips_signal_error ("cipher mode NONE used");
- rc = GPG_ERR_INV_CIPHER_MODE;
- }
- else
- {
- if (inbuf != outbuf)
- memmove (outbuf, inbuf, nbytes);
- }
- break;
- default:
- log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
- rc = GPG_ERR_INV_CIPHER_MODE;
- break;
+ switch (c->mode)
+ {
+ case GCRY_CIPHER_MODE_ECB:
+ rc = do_ecb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CBC:
+ rc = do_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CFB:
+ rc = do_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_OFB:
+ rc = do_ofb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CTR:
+ rc = do_ctr_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_AESWRAP:
+ rc = do_aeswrap_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_STREAM:
+ c->cipher->stdecrypt (&c->context.c,
+ outbuf, (byte*)/*arggg*/inbuf, inbuflen);
+ rc = 0;
+ break;
+
+ case GCRY_CIPHER_MODE_NONE:
+ if (fips_mode () || !_gcry_get_debug_flag (0))
+ {
+ fips_signal_error ("cipher mode NONE used");
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+ else
+ {
+ if (inbuf != outbuf)
+ memmove (outbuf, inbuf, inbuflen);
+ rc = 0;
+ }
+ break;
+
+ default:
+ log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
}
- return rc;
+
+ return rc;
}
@@ -1554,25 +1806,12 @@ gcry_error_t
gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
const void *in, size_t inlen)
{
- gcry_err_code_t err = 0;
+ gcry_err_code_t err;
- if (!in)
- {
- /* Caller requested in-place encryption. */
- /* Actually cipher_encrypt() does not need to know about it, but
- * we may change it in the future to get better performance. */
- err = cipher_decrypt (h, out, out, outsize);
- }
- else if (outsize < inlen)
- err = GPG_ERR_TOO_SHORT;
- else if (((h->mode == GCRY_CIPHER_MODE_ECB)
- || ((h->mode == GCRY_CIPHER_MODE_CBC)
- && (! ((h->flags & GCRY_CIPHER_CBC_CTS)
- && (inlen > h->cipher->blocksize)))))
- && (inlen % h->cipher->blocksize) != 0)
- err = GPG_ERR_INV_ARG;
+ if (!in) /* Caller requested in-place encryption. */
+ err = cipher_decrypt (h, out, outsize, out, outsize);
else
- err = cipher_decrypt (h, out, in, inlen);
+ err = cipher_decrypt (h, out, outsize, in, inlen);
return gcry_error (err);
}
@@ -1732,7 +1971,7 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
There are no values for CMD yet defined.
- The fucntion always returns GPG_ERR_INV_OP.
+ The function always returns GPG_ERR_INV_OP.
*/
gcry_error_t
@@ -1774,7 +2013,7 @@ gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
Note: Because this function is in most cases used to return an
integer value, we can make it easier for the caller to just look at
the return value. The caller will in all cases consult the value
- and thereby detecting whether a error occured or not (i.e. while
+ and thereby detecting whether a error occurred or not (i.e. while
checking the block size)
*/
gcry_error_t
diff --git a/grub-core/lib/libgcrypt/cipher/crc.c b/grub-core/lib/libgcrypt/cipher/crc.c
index d04fff8..9e406f1 100644
--- a/grub-core/lib/libgcrypt/cipher/crc.c
+++ b/grub-core/lib/libgcrypt/cipher/crc.c
@@ -25,7 +25,6 @@
#include <string.h>
#include "g10lib.h"
-#include "memory.h"
#include "cipher.h"
#include "bithelp.h"
diff --git a/grub-core/lib/libgcrypt/cipher/des.c b/grub-core/lib/libgcrypt/cipher/des.c
index f91df77..e7f14fd 100644
--- a/grub-core/lib/libgcrypt/cipher/des.c
+++ b/grub-core/lib/libgcrypt/cipher/des.c
@@ -106,7 +106,7 @@
*
* if ( (error_msg = selftest()) )
* {
- * fprintf(stderr, "An error in the DES/Tripple-DES implementation occured: %s\n", error_msg);
+ * fprintf(stderr, "An error in the DES/Triple-DES implementation occurred: %s\n", error_msg);
* abort();
* }
*/
diff --git a/grub-core/lib/libgcrypt/cipher/dsa.c b/grub-core/lib/libgcrypt/cipher/dsa.c
index 100710f..ceb9496 100644
--- a/grub-core/lib/libgcrypt/cipher/dsa.c
+++ b/grub-core/lib/libgcrypt/cipher/dsa.c
@@ -907,6 +907,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
gcry_mpi_release ((*retfactors)[i]);
(*retfactors)[i] = NULL;
}
+ gcry_free (*retfactors);
*retfactors = NULL;
if (ec)
{
diff --git a/grub-core/lib/libgcrypt/cipher/ecc.c b/grub-core/lib/libgcrypt/cipher/ecc.c
index fcbd8e3..bcfab05 100644
--- a/grub-core/lib/libgcrypt/cipher/ecc.c
+++ b/grub-core/lib/libgcrypt/cipher/ecc.c
@@ -1,5 +1,5 @@
/* ecc.c - Elliptic Curve Cryptography
- Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
This file is part of Libgcrypt.
@@ -504,6 +504,7 @@ generate_curve (unsigned int nbits, const char *name,
*/
static gpg_err_code_t
generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
+ int transient_key,
gcry_mpi_t g_x, gcry_mpi_t g_y,
gcry_mpi_t q_x, gcry_mpi_t q_y)
{
@@ -512,6 +513,7 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
gcry_mpi_t d;
mpi_point_t Q;
mpi_ec_t ctx;
+ gcry_random_level_t random_level;
err = generate_curve (nbits, name, &E, &nbits);
if (err)
@@ -528,9 +530,11 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
log_mpidump ("ecc generation Gz", E.G.z);
}
+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
if (DBG_CIPHER)
- log_debug ("choosing a random x of size %u\n", nbits);
- d = gen_k (E.n, GCRY_VERY_STRONG_RANDOM);
+ log_debug ("choosing a random x of size %u%s\n", nbits,
+ transient_key? " (transient-key)":"");
+ d = gen_k (E.n, random_level);
/* Compute Q. */
point_init (&Q);
@@ -962,6 +966,7 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
gcry_mpi_t g_x, g_y, q_x, q_y;
char *curve_name = NULL;
gcry_sexp_t l1;
+ int transient_key = 0;
(void)algo;
(void)evalue;
@@ -978,6 +983,14 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
if (!curve_name)
return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
}
+
+ /* Parse the optional transient-key flag. */
+ l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+ if (l1)
+ {
+ transient_key = 1;
+ gcry_sexp_release (l1);
+ }
}
/* NBITS is required if no curve name has been given. */
@@ -988,7 +1001,7 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
g_y = mpi_new (0);
q_x = mpi_new (0);
q_y = mpi_new (0);
- ec = generate_key (&sk, nbits, curve_name, g_x, g_y, q_x, q_y);
+ ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y);
gcry_free (curve_name);
if (ec)
return ec;
@@ -1266,7 +1279,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
}
/* Check that all parameters are known and normalize all MPIs (that
- should not be required but we use an internal fucntion later and
+ should not be required but we use an internal function later and
thus we better make 100% sure that they are normalized). */
for (idx = 0; idx < 6; idx++)
if (!values[idx])
diff --git a/grub-core/lib/libgcrypt/cipher/md.c b/grub-core/lib/libgcrypt/cipher/md.c
index 5dfbbd9..5f12126 100644
--- a/grub-core/lib/libgcrypt/cipher/md.c
+++ b/grub-core/lib/libgcrypt/cipher/md.c
@@ -87,6 +87,10 @@ static struct digest_table_entry
#if USE_TIGER
{ &_gcry_digest_spec_tiger,
&dummy_extra_spec, GCRY_MD_TIGER },
+ { &_gcry_digest_spec_tiger1,
+ &dummy_extra_spec, GCRY_MD_TIGER1 },
+ { &_gcry_digest_spec_tiger2,
+ &dummy_extra_spec, GCRY_MD_TIGER2 },
#endif
#if USE_WHIRLPOOL
{ &_gcry_digest_spec_whirlpool,
@@ -101,7 +105,7 @@ static gcry_module_t digests_registered;
/* This is the lock protecting DIGESTS_REGISTERED. */
static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
-/* Flag to check wether the default ciphers have already been
+/* Flag to check whether the default ciphers have already been
registered. */
static int default_digests_registered;
@@ -948,10 +952,13 @@ md_read( gcry_md_hd_t a, int algo )
if (! algo)
{
- /* return the first algorithm */
- if (r && r->next)
- log_debug ("more than one algorithm in md_read(0)\n");
- return r->digest->read( &r->context.c );
+ /* Return the first algorithm */
+ if (r)
+ {
+ if (r->next)
+ log_debug ("more than one algorithm in md_read(0)\n");
+ return r->digest->read (&r->context.c);
+ }
}
else
{
@@ -1135,7 +1142,7 @@ md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
* Note: Because this function is in most cases used to return an
* integer value, we can make it easier for the caller to just look at
* the return value. The caller will in all cases consult the value
- * and thereby detecting whether a error occured or not (i.e. while checking
+ * and thereby detecting whether a error occurred or not (i.e. while checking
* the block size)
*/
gcry_error_t
diff --git a/grub-core/lib/libgcrypt/cipher/md4.c b/grub-core/lib/libgcrypt/cipher/md4.c
index aa180f0..976036c 100644
--- a/grub-core/lib/libgcrypt/cipher/md4.c
+++ b/grub-core/lib/libgcrypt/cipher/md4.c
@@ -53,7 +53,6 @@
#include <string.h>
#include "g10lib.h"
-#include "memory.h"
#include "cipher.h"
#include "bithelp.h"
diff --git a/grub-core/lib/libgcrypt/cipher/md5.c b/grub-core/lib/libgcrypt/cipher/md5.c
index 3d3046d..1993368 100644
--- a/grub-core/lib/libgcrypt/cipher/md5.c
+++ b/grub-core/lib/libgcrypt/cipher/md5.c
@@ -37,7 +37,6 @@
#include <string.h>
#include "g10lib.h"
-#include "memory.h"
#include "cipher.h"
#include "bithelp.h"
diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/grub-core/lib/libgcrypt/cipher/primegen.c
index b869bee..f072775 100644
--- a/grub-core/lib/libgcrypt/cipher/primegen.c
+++ b/grub-core/lib/libgcrypt/cipher/primegen.c
@@ -988,7 +988,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
/* Given ARRAY of size N with M elements set to true produce a
modified array with the next permutation of M elements. Note, that
ARRAY is used in a one-bit-per-byte approach. To detected the last
- permutation it is useful to intialize the array with the first M
+ permutation it is useful to initialize the array with the first M
element set to true and use this test:
m_out_of_n (array, m, n);
for (i = j = 0; i < n && j < m; i++)
@@ -1170,7 +1170,7 @@ gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
return gcry_error (err);
}
-/* Check wether the number X is prime. */
+/* Check whether the number X is prime. */
gcry_error_t
gcry_prime_check (gcry_mpi_t x, unsigned int flags)
{
diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/grub-core/lib/libgcrypt/cipher/pubkey.c
index 08abcbf..86693e8 100644
--- a/grub-core/lib/libgcrypt/cipher/pubkey.c
+++ b/grub-core/lib/libgcrypt/cipher/pubkey.c
@@ -85,7 +85,7 @@ static gcry_module_t pubkeys_registered;
/* This is the lock protecting PUBKEYS_REGISTERED. */
static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
-/* Flag to check wether the default pubkeys have already been
+/* Flag to check whether the default pubkeys have already been
registered. */
static int default_pubkeys_registered;
@@ -1567,7 +1567,7 @@ sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
Do a PK encrypt operation
Caller has to provide a public key as the SEXP pkey and data as a
- SEXP with just one MPI in it. Alternativly S_DATA might be a
+ SEXP with just one MPI in it. Alternatively S_DATA might be a
complex S-Expression, similar to the one used for signature
verification. This provides a flag which allows to handle PKCS#1
block type 2 padding. The function returns a a sexp which may be
@@ -2357,7 +2357,7 @@ gcry_pk_get_nbits (gcry_sexp_t key)
/* Return the so called KEYGRIP which is the SHA-1 hash of the public
- key parameters expressed in a way depended on the algorithm.
+ key parameters expressed in a way depending on the algorithm.
ARRAY must either be 20 bytes long or NULL; in the latter case a
newly allocated array of that size is returned, otherwise ARRAY or
@@ -2503,15 +2503,15 @@ gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
care or a combination of the GCRY_PK_USAGE_xxx flags;
GCRYCTL_GET_ALGO_USAGE:
- Return the usage glafs for the give algo. An invalid alog
- does return 0. Disabled algos are ignored here becuase we
+ Return the usage flags for the given algo. An invalid algo
+ returns 0. Disabled algos are ignored here because we
only want to know whether the algo is at all capable of
the usage.
Note: Because this function is in most cases used to return an
integer value, we can make it easier for the caller to just look at
the return value. The caller will in all cases consult the value
- and thereby detecting whether a error occured or not (i.e. while
+ and thereby detecting whether a error occurred or not (i.e. while
checking the block size) */
gcry_error_t
gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
diff --git a/grub-core/lib/libgcrypt/cipher/rfc2268.c b/grub-core/lib/libgcrypt/cipher/rfc2268.c
index 7d63fce..9575ca6 100644
--- a/grub-core/lib/libgcrypt/cipher/rfc2268.c
+++ b/grub-core/lib/libgcrypt/cipher/rfc2268.c
@@ -22,7 +22,7 @@
/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
* as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
* direct use by Libgcrypt by Werner Koch. This implementation is
- * only useful for pkcs#12 descryption.
+ * only useful for pkcs#12 decryption.
*
* The implementation here is based on Peter Gutmann's RRC.2 paper.
*/
diff --git a/grub-core/lib/libgcrypt/cipher/rmd160.c b/grub-core/lib/libgcrypt/cipher/rmd160.c
index 73d5337..7223c0f 100644
--- a/grub-core/lib/libgcrypt/cipher/rmd160.c
+++ b/grub-core/lib/libgcrypt/cipher/rmd160.c
@@ -24,7 +24,6 @@
#include <string.h>
#include "g10lib.h"
-#include "memory.h"
#include "rmd.h"
#include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
diff --git a/grub-core/lib/libgcrypt/cipher/rsa.c b/grub-core/lib/libgcrypt/cipher/rsa.c
index cf278c2..6102cc4 100644
--- a/grub-core/lib/libgcrypt/cipher/rsa.c
+++ b/grub-core/lib/libgcrypt/cipher/rsa.c
@@ -444,18 +444,28 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
else
{
/* Parameters to derive the key are given. */
+ /* Note that we explicitly need to setup the values of tbl
+ because some compilers (e.g. OpenWatcom, IRIX) don't allow
+ to initialize a structure with automatic variables. */
struct { const char *name; gcry_mpi_t *value; } tbl[] = {
- { "Xp1", &xp1 },
- { "Xp2", &xp2 },
- { "Xp", &xp },
- { "Xq1", &xq1 },
- { "Xq2", &xq2 },
- { "Xq", &xq },
- { NULL, NULL }
+ { "Xp1" },
+ { "Xp2" },
+ { "Xp" },
+ { "Xq1" },
+ { "Xq2" },
+ { "Xq" },
+ { NULL }
};
int idx;
gcry_sexp_t oneparm;
+ tbl[0].value = &xp1;
+ tbl[1].value = &xp2;
+ tbl[2].value = &xp;
+ tbl[3].value = &xq1;
+ tbl[4].value = &xq2;
+ tbl[5].value = &xq;
+
for (idx=0; tbl[idx].name; idx++)
{
oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0);
@@ -572,7 +582,7 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
/****************
- * Test wether the secret key is valid.
+ * Test whether the secret key is valid.
* Returns: true if this is a valid key.
*/
static int
@@ -876,7 +886,7 @@ rsa_check_secret_key (int algo, gcry_mpi_t *skey)
err = GPG_ERR_NO_OBJ; /* To check the key we need the optional
parameters. */
else if (!check_secret_key (&sk))
- err = GPG_ERR_PUBKEY_ALGO;
+ err = GPG_ERR_BAD_SECKEY;
return err;
}
@@ -942,7 +952,7 @@ rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
gcry_mpi_mod (r, r, sk.n);
/* Calculate inverse of r. It practically impossible that the
- follwing test fails, thus we do not add code to release
+ following test fails, thus we do not add code to release
allocated resources. */
if (!gcry_mpi_invm (ri, r, sk.n))
return GPG_ERR_INTERNAL;
@@ -1053,7 +1063,7 @@ rsa_get_nbits (int algo, gcry_mpi_t *pkey)
(e #010001#))
PKCS-15 says that for RSA only the modulus should be hashed -
- however, it is not clear wether this is meant to use the raw bytes
+ however, it is not clear whether this is meant to use the raw bytes
(assuming this is an unsigned integer) or whether the DER required
0 should be prefixed. We hash the raw bytes. */
static gpg_err_code_t
diff --git a/grub-core/lib/libgcrypt/cipher/sha1.c b/grub-core/lib/libgcrypt/cipher/sha1.c
index 8862c64..0b5dc43 100644
--- a/grub-core/lib/libgcrypt/cipher/sha1.c
+++ b/grub-core/lib/libgcrypt/cipher/sha1.c
@@ -37,7 +37,6 @@
#endif
#include "g10lib.h"
-#include "memory.h"
#include "bithelp.h"
#include "cipher.h"
#include "hash-common.h"
diff --git a/grub-core/lib/libgcrypt/cipher/sha256.c b/grub-core/lib/libgcrypt/cipher/sha256.c
index 5d61d2f..8063592 100644
--- a/grub-core/lib/libgcrypt/cipher/sha256.c
+++ b/grub-core/lib/libgcrypt/cipher/sha256.c
@@ -1,5 +1,5 @@
/* sha256.c - SHA256 hash function
- * Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -41,7 +41,6 @@
#include <string.h>
#include "g10lib.h"
-#include "memory.h"
#include "bithelp.h"
#include "cipher.h"
#include "hash-common.h"
@@ -95,10 +94,6 @@ sha224_init (void *context)
/*
Transform the message X which consists of 16 32-bit-words. See FIPS
180-2 for details. */
-#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
-#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
-#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
-#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
#define R(a,b,c,d,e,f,g,h,k,w) do \
@@ -114,6 +109,35 @@ sha224_init (void *context)
b = a; \
a = t1 + t2; \
} while (0)
+
+/* (4.2) same as SHA-1's F1. */
+static inline u32
+Cho (u32 x, u32 y, u32 z)
+{
+ return (z ^ (x & (y ^ z)));
+}
+
+/* (4.3) same as SHA-1's F3 */
+static inline u32
+Maj (u32 x, u32 y, u32 z)
+{
+ return ((x & y) | (z & (x|y)));
+}
+
+/* (4.4) */
+static inline u32
+Sum0 (u32 x)
+{
+ return (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22));
+}
+
+/* (4.5) */
+static inline u32
+Sum1 (u32 x)
+{
+ return (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25));
+}
+
static void
transform (SHA256_CONTEXT *hd, const unsigned char *data)
@@ -172,8 +196,55 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data)
for (; i < 64; i++)
w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
- for (i=0; i < 64; i++)
- R(a,b,c,d,e,f,g,h,K[i],w[i]);
+ for (i=0; i < 64;)
+ {
+#if 0
+ R(a,b,c,d,e,f,g,h,K[i],w[i]);
+ i++;
+#else
+ t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Cho (d, e, f) + K[i+1] + w[i+1];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Cho (c, d, e) + K[i+2] + w[i+2];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Cho (b, c, d) + K[i+3] + w[i+3];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Cho (a, b, c) + K[i+4] + w[i+4];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Cho (h, a, b) + K[i+5] + w[i+5];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Cho (g, h, a) + K[i+6] + w[i+6];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Cho (f, g, h) + K[i+7] + w[i+7];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ i += 8;
+#endif
+ }
hd->h0 += a;
hd->h1 += b;
@@ -184,10 +255,6 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data)
hd->h6 += g;
hd->h7 += h;
}
-#undef Cho
-#undef Maj
-#undef Sum0
-#undef Sum1
#undef S0
#undef S1
#undef R
diff --git a/grub-core/lib/libgcrypt/cipher/sha512.c b/grub-core/lib/libgcrypt/cipher/sha512.c
index bbbd4c5..59c3e65 100644
--- a/grub-core/lib/libgcrypt/cipher/sha512.c
+++ b/grub-core/lib/libgcrypt/cipher/sha512.c
@@ -1,5 +1,5 @@
/* sha512.c - SHA384 and SHA512 hash functions
- * Copyright (C) 2003, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2008, 2009 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -98,6 +98,36 @@ sha384_init (void *context)
}
+static inline u64
+ROTR (u64 x, u64 n)
+{
+ return ((x >> n) | (x << (64 - n)));
+}
+
+static inline u64
+Ch (u64 x, u64 y, u64 z)
+{
+ return ((x & y) ^ ( ~x & z));
+}
+
+static inline u64
+Maj (u64 x, u64 y, u64 z)
+{
+ return ((x & y) ^ (x & z) ^ (y & z));
+}
+
+static inline u64
+Sum0 (u64 x)
+{
+ return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39));
+}
+
+static inline u64
+Sum1 (u64 x)
+{
+ return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
+}
+
/****************
* Transform the message W which consists of 16 64-bit-words
*/
@@ -182,21 +212,26 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data)
}
#endif
-#define ROTR(x,n) (((x)>>(n)) | ((x)<<(64-(n))))
-#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-#define Sum0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
-#define Sum1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
for (t = 16; t < 80; t++)
w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
- for (t = 0; t < 80; t++)
+
+ for (t = 0; t < 80; )
{
u64 t1, t2;
+ /* Performance on a AMD Athlon(tm) Dual Core Processor 4050e
+ with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes
+ initialized to 0,1,2,3...255,0,... and 1000 iterations:
+
+ Not unrolled with macros: 440ms
+ Unrolled with macros: 350ms
+ Unrolled with inline: 330ms
+ */
+#if 0 /* Not unrolled. */
t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
t2 = Sum0 (a) + Maj (a, b, c);
h = g;
@@ -207,12 +242,53 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data)
c = b;
b = a;
a = t1 + t2;
-
- /* printf("t=%d a=%016llX b=%016llX c=%016llX d=%016llX "
- "e=%016llX f=%016llX g=%016llX h=%016llX\n",t,a,b,c,d,e,f,g,h); */
+ t++;
+#else /* Unrolled to interweave the chain variables. */
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[t+1];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[t+2];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[t+3];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[t+4];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[t+5];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[t+6];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[t+7];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t += 8;
+#endif
}
- /* update chaining vars */
+ /* Update chaining vars. */
hd->h0 += a;
hd->h1 += b;
hd->h2 += c;
diff --git a/grub-core/lib/libgcrypt/cipher/test-getrusage.c b/grub-core/lib/libgcrypt/cipher/test-getrusage.c
new file mode 100644
index 0000000..479eaab
--- /dev/null
+++ b/grub-core/lib/libgcrypt/cipher/test-getrusage.c
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+
+int
+main (int argc, char **argv)
+{
+ struct rusage buf;
+
+ if (argc > 1)
+ {
+ system (argv[1]);
+
+ if (getrusage (RUSAGE_CHILDREN, &buf ))
+ {
+ perror ("getrusage");
+ return 1;
+ }
+ }
+ else
+ {
+ if (getrusage (RUSAGE_SELF, &buf ))
+ {
+ perror ("getrusage");
+ return 1;
+ }
+ }
+
+ printf ("ru_utime = %ld.%06ld\n",
+ buf.ru_utime.tv_sec, buf.ru_utime.tv_usec);
+ printf ("ru_stime = %ld.%06ld\n",
+ buf.ru_stime.tv_sec, buf.ru_stime.tv_usec);
+ printf ("ru_maxrss = %ld\n", buf.ru_maxrss );
+ printf ("ru_ixrss = %ld\n", buf.ru_ixrss );
+ printf ("ru_idrss = %ld\n", buf.ru_idrss );
+ printf ("ru_isrss = %ld\n", buf.ru_isrss );
+ printf ("ru_minflt = %ld\n", buf.ru_minflt );
+ printf ("ru_majflt = %ld\n", buf.ru_majflt );
+ printf ("ru_nswap = %ld\n", buf.ru_nswap );
+ printf ("ru_inblock = %ld\n", buf.ru_inblock );
+ printf ("ru_oublock = %ld\n", buf.ru_oublock );
+ printf ("ru_msgsnd = %ld\n", buf.ru_msgsnd );
+ printf ("ru_msgrcv = %ld\n", buf.ru_msgrcv );
+ printf ("ru_nsignals= %ld\n", buf.ru_nsignals );
+ printf ("ru_nvcsw = %ld\n", buf.ru_nvcsw );
+ printf ("ru_nivcsw = %ld\n", buf.ru_nivcsw );
+
+ fprintf (stderr, "ru_utime ru_stime ru_minflt ru_nccsw ru_nivcsw\n");
+ fprintf (stderr, "%ld.%06ld %ld.%06ld %5ld %5ld %5ld\n");
+
+
+ return 0;
+}
+
+
+/* Codesnippet for debugging in random.c. */
+#if 0
+static void
+collect_rusage_stats (struct rusage *rb)
+{
+ static int idx;
+ static struct rusage buf[100];
+
+ if (!rb)
+ {
+ int i;
+
+ fprintf (stderr, "ru_utime ru_stime ru_minflt ru_nvcsw ru_nivcsw\n");
+ for (i=0; i < idx; i++)
+ fprintf (stderr, "%ld.%06ld %ld.%06ld %5ld %5ld %5ld\n",
+ buf[i].ru_utime.tv_sec, buf[i].ru_utime.tv_usec,
+ buf[i].ru_stime.tv_sec, buf[i].ru_stime.tv_usec,
+ buf[i].ru_minflt,
+ buf[i].ru_nvcsw,
+ buf[i].ru_nivcsw);
+ }
+ else if (idx < DIM(buf))
+ {
+ buf[idx++] = *rb;
+ }
+}
+#endif
+/*
+ void
+ _gcry_random_dump_stats()
+ {
+@@ -233,8 +261,11 @@
+ rndstats.naddbytes, rndstats.addbytes,
+ rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
+ rndstats.ngetbytes2, rndstats.getbytes2 );
++
++ collect_rusage_stats (NULL);
+ }
+
+========
+
+ getrusage (RUSAGE_SELF, &buf );
++ collect_rusage_stats (&buf);
+ add_randomness( &buf, sizeof buf, 1 );
+ memset( &buf, 0, sizeof buf );
+ }
+
+*/
+
+
diff --git a/grub-core/lib/libgcrypt/cipher/tiger.c b/grub-core/lib/libgcrypt/cipher/tiger.c
index a620045..4ad6ce5 100644
--- a/grub-core/lib/libgcrypt/cipher/tiger.c
+++ b/grub-core/lib/libgcrypt/cipher/tiger.c
@@ -1,5 +1,5 @@
/* tiger.c - The TIGER hash function
- * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2001, 2002, 2003, 2010 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -18,25 +18,26 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
+/* See http://www.cs.technion.ac.il/~biham/Reports/Tiger/ */
+
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g10lib.h"
-#include "memory.h"
#include "cipher.h"
+/* We really need a 64 bit type for this code. */
#ifdef HAVE_U64_TYPEDEF
-/* we really need it here, but as this is only experiment we
- * can live without Tiger */
-
-typedef struct {
- u64 a, b, c;
- byte buf[64];
- int count;
- u32 nblocks;
+typedef struct
+{
+ u64 a, b, c;
+ byte buf[64];
+ int count;
+ u32 nblocks;
+ int variant; /* 0 = old code, 1 = fixed code, 2 - TIGER2. */
} TIGER_CONTEXT;
@@ -588,7 +589,7 @@ static u64 sbox4[256] = {
};
static void
-tiger_init( void *context )
+do_init (void *context, int variant)
{
TIGER_CONTEXT *hd = context;
@@ -597,6 +598,25 @@ tiger_init( void *context )
hd->c = 0xf096a5b4c3b2e187LL;
hd->nblocks = 0;
hd->count = 0;
+ hd->variant = variant;
+}
+
+static void
+tiger_init (void *context)
+{
+ do_init (context, 0);
+}
+
+static void
+tiger1_init (void *context)
+{
+ do_init (context, 1);
+}
+
+static void
+tiger2_init (void *context)
+{
+ do_init (context, 2);
}
static void
@@ -763,6 +783,7 @@ tiger_final( void *context )
TIGER_CONTEXT *hd = context;
u32 t, msb, lsb;
byte *p;
+ byte pad = hd->variant == 2? 0x80 : 0x01;
tiger_write(hd, NULL, 0); /* flush */;
@@ -782,13 +803,13 @@ tiger_final( void *context )
if( hd->count < 56 ) /* enough room */
{
- hd->buf[hd->count++] = 0x01; /* pad */
+ hd->buf[hd->count++] = pad;
while( hd->count < 56 )
hd->buf[hd->count++] = 0; /* pad */
}
else /* need one extra block */
{
- hd->buf[hd->count++] = 0x01; /* pad character */
+ hd->buf[hd->count++] = pad; /* pad character */
while( hd->count < 64 )
hd->buf[hd->count++] = 0;
tiger_write(hd, NULL, 0); /* flush */;
@@ -815,10 +836,24 @@ tiger_final( void *context )
*p++ = hd->a >> 24; *p++ = hd->a >> 16; \
*p++ = hd->a >> 8; *p++ = hd->a; } while(0)
#endif
- X(a);
- X(b);
- X(c);
+#define Y(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
+ *p++ = hd->a >> 16; *p++ = hd->a >> 24; \
+ *p++ = hd->a >> 32; *p++ = hd->a >> 40; \
+ *p++ = hd->a >> 48; *p++ = hd->a >> 56; } while(0)
+ if (hd->variant == 0)
+ {
+ X(a);
+ X(b);
+ X(c);
+ }
+ else
+ {
+ Y(a);
+ Y(b);
+ Y(c);
+ }
#undef X
+#undef Y
}
static byte *
@@ -829,22 +864,47 @@ tiger_read( void *context )
return hd->buf;
}
-static byte asn[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
+
+
+/* This is the old TIGER variant based on the unfixed reference
+ implementation. IT was used in GnupG up to 1.3.2. We don't provide
+ an OID anymore because that would not be correct. */
+gcry_md_spec_t _gcry_digest_spec_tiger =
+ {
+ "TIGER192", NULL, 0, NULL, 24,
+ tiger_init, tiger_write, tiger_final, tiger_read,
+ sizeof (TIGER_CONTEXT)
+ };
+
+
+
+/* This is the fixed TIGER implementation. */
+static byte asn1[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
{ 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
0x05, 0x00, 0x04, 0x18 };
-static gcry_md_oid_spec_t oid_spec_tiger[] =
+static gcry_md_oid_spec_t oid_spec_tiger1[] =
{
/* GNU.digestAlgorithm TIGER */
{ "1.3.6.1.4.1.11591.12.2" },
{ NULL }
};
-gcry_md_spec_t _gcry_digest_spec_tiger =
+gcry_md_spec_t _gcry_digest_spec_tiger1 =
{
- "TIGER192", asn, DIM (asn), oid_spec_tiger, 24,
- tiger_init, tiger_write, tiger_final, tiger_read,
+ "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
+ tiger1_init, tiger_write, tiger_final, tiger_read,
+ sizeof (TIGER_CONTEXT)
+ };
+
+
+
+/* This is TIGER2 which usues a changed padding algorithm. */
+gcry_md_spec_t _gcry_digest_spec_tiger2 =
+ {
+ "TIGER2", NULL, 0, NULL, 24,
+ tiger2_init, tiger_write, tiger_final, tiger_read,
sizeof (TIGER_CONTEXT)
};
diff --git a/grub-core/lib/libgcrypt/cipher/twofish.c b/grub-core/lib/libgcrypt/cipher/twofish.c
index 5274c40..68b2c7a 100644
--- a/grub-core/lib/libgcrypt/cipher/twofish.c
+++ b/grub-core/lib/libgcrypt/cipher/twofish.c
@@ -522,7 +522,7 @@ static byte calc_sb_tbl[512] = {
* preprocessed through q0 and q1 respectively; for longer keys they are the
* output of previous stages. j is the index of the first key byte to use.
* CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
- * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
+ * twice, doing the Pseudo-Hadamard Transform, and doing the necessary
* rotations. Its parameters are: a, the array to write the results into,
* j, the index of the first output entry, k and l, the preprocessed indices
* for index 2i, and m and n, the preprocessed indices for index 2i+1.
diff --git a/grub-core/lib/libgcrypt/cipher/whirlpool.c b/grub-core/lib/libgcrypt/cipher/whirlpool.c
index 9b029ee..e6c226c 100644
--- a/grub-core/lib/libgcrypt/cipher/whirlpool.c
+++ b/grub-core/lib/libgcrypt/cipher/whirlpool.c
@@ -36,7 +36,6 @@
#include "types.h"
#include "g10lib.h"
-#include "memory.h"
#include "cipher.h"
#include "bithelp.h"
diff --git a/grub-core/lib/libgcrypt/mpi/ChangeLog-2011 b/grub-core/lib/libgcrypt/mpi/ChangeLog-2011
new file mode 100644
index 0000000..1e07872
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/ChangeLog-2011
@@ -0,0 +1,831 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-07-04 Werner Koch <wk@g10code.com>
+
+ * longlong.h (add_ssaaaa) [__arm__]: Do no use asm if thumb code
+ generation is enabled. This is bug#1202. Reported for gpg 1.4.
+
+2011-03-28 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Remove unused var RSEC.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * mpi-cmp.c (gcry_mpi_cmp): Allow comparing of opaque MPIs.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-02-22 Aurelien Jarno <aurel32@debian.org> (wk)
+
+ * longlong.h (umul_ppmm) <mips> [__GNUC__ >= 4.4]: Patch according
+ to recommended gcc 4.4 changes.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * config.links: Remove asm modules for all sparc64. This is
+ debian#560028.
+
+2009-05-26 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (mpi_read_from_buffer): Allow zero-sized MPIs (i.e a
+ zero).
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * mpiutil.c: Remove memory.h.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (mpi_read_from_buffer): Do not bail out if the mpi is
+ larger than the buffer (potential problem). Do not print error
+ messages.
+ (mpi_fromstr): Return an error instead of hitting an assert.
+ (gcry_mpi_scan) <PGP>: Fix potential double free problem.
+ (gcry_mpi_scan) <HEX>: Fix potential memory leak.
+ (do_get_buffer): Return NULL on memory allocation failure.
+ (gcry_mpi_print): Check result of do_get_buffer.
+ (gcry_mpi_aprint): Return error on a memory allocation failure.
+
+ * mpicoder.c: Re-indent.
+
+2008-12-03 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Fix last change. Asserts are really
+ useful!
+
+2008-12-02 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Re-indent.
+ (gcry_mpi_powm): Simplified allocation of the result to fix a
+ double free bug. This is bug#977. Reported by Haakon Ringberg.
+
+2008-08-20 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_lshift): Actually implement.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_lshift): New.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * mpi-mod.c (gcry_mpi_mod): Remove
+ * mpi-inv.c (_gcry_mpi_invm): Remove _ prefix.
+ * mpiutil.c (_gcry_mpi_swap): Remove.
+ (_gcry_mpi_new): Remove.
+ (_gcry_mpi_snew): Remove.
+ (gcry_mpi_invm): Remove.
+ (gcry_mpi_copy): Remove and rename _version to this.
+ (gcry_mpi_set, gcry_mpi_set_ui): Merge with _ version.
+ * mpi-inv.c (gcry_mpi_invm): Remove _ prefix and return 1.
+ * mpi-mul.c (gcry_mpi_mul_2exp): Remove and rename _ version to this.
+
+2007-10-29 Werner Koch <wk@g10code.com>
+
+ * config.links: No Candadian Cross here, thus use $host instead of
+ $target.
+
+2007-10-26 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Special rules for Apple
+ Darwin on ia32 from Gregor Riepl.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * config.links: Rename assembler file links by suffixing "-asm".
+ * Makefile.am (CCASCOMPILE, LTCCASCOMPILE, CLEANFILES,
+ libmpi_la_LIBADD, libmpi_la_DEPENDENCIES, SUFFIXES, .S.o, .S.obj,
+ .S.lo): Removed variables and targets.
+ (mpih_add1, mpih_sub1, mpih_mul1, mpih_mul2, mpih_mul3,
+ mpih_lshift, mpih_rshift, mpih_udiv, mpih_udiv_qrnnd,
+ nodist_libmpi_la_SOURCES): New variables.
+ (DISTCLEANFILES): Rename assembler file links by suffixing "-asm".
+ Add variants for C file links.
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ * config.links (path): Allowthe sue of colons as delimiters.
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * pentium4/distfiles: Fixed.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * config.links: Create a file mod-source-info.h.
+ * Makefile.am (DISTCLEANFILES): Add that file.
+ * mpiutil.c (_gcry_mpi_get_hw_config): New.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * config.links: Add additional assembler search directories.
+
+2007-03-28 Werner Koch <wk@g10code.com>
+
+ * ec.c: New.
+
+2007-03-23 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (_gcry_mpi_lshift_limbs): Assign AP after the resize.
+
+ * mpi-div.c (gcry_mpi_mod, _gcry_mpi_mod): Moved to ..
+ * mpi-mod.c: .. new file.
+ (_gcry_mpi_barrett_init, _gcry_mpi_barrett_free): New.
+ (_gcry_mpi_mod_barrett): New.
+ (_gcry_mpi_mul_barrett): New.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * mpi-div.c (_gcry_mpi_mod): New.
+ * mpiutil.c (_gcry_mpi_new, _gcry_mpi_snew): New.
+
+2007-03-13 Werner Dittmann <Werner.Dittmann@t-online.de> (wk)
+
+ * amd64/mpih-add1.S, amd64/mpih-add1.S, amd64/mpih-lshift.S
+ * amd64/mpih-mul1.S, amd64/mpih-mul2.S, amd64/mpih-mul3.S
+ * amd64/mpih-rshift.S, amd64/mpih-sub1.S: New.
+ * config.links: Add case for x86_64.
+
+2007-02-23 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Remove unused var ESIGN.
+
+ * mpiutil.c (gcry_mpi_get_flag): Let it return a value to silent
+ MIPSpro cc warning.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (_gcry_mpi_set_buffer): Made BUFFER a void*.
+
+2006-11-15 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (.S.o): Check for srcdir also in in CPP pass.
+ (INCLUDES): Removed.
+ (AM_CPPFLAGS, AM_CFLAGS): New, modified. Merged with Moritz'
+ changes.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
+ new gcrypt.h is used, not the one installed in the system.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Make sure that powerpc64 is
+ matched before a generic powerpc. Reported by Andreas Metzler.
+ Should fix Debian bug 284609.
+
+2006-08-25 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_rshift): Don't shift if N == 0 but do a
+ plain copy.
+
+2006-08-04 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_rshift): Rewritten to remove the limitation
+ on N (which used to be less than BITS_PER_MPI_LIMB).
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit): Fixed
+ allocation. Reported by bpgcrypt at itaparica.org.
+ * mpiutil.c (_gcry_mpi_resize): Clear the new part of the resized
+ limb space.
+
+2006-07-26 Werner Koch <wk@g10code.com>
+
+ * mpiutil.c (gcry_mpi_randomize): Changed P to unsigned char*.
+
+ * mpicoder.c (gcry_mpi_scan): Changed arg BUFFER to void*.
+ (mpi_read_from_buffer): Made BUFFER arg const.
+ (gcry_mpi_scan): Removed now needless cast. Add cast for arg to
+ mpi_fromstr.
+ (gcry_mpi_print): Made TMP unsigned.
+
+ * Makefile.am (AM_CCASFLAGS): New.
+
+2005-10-09 Moritz Schulte <moritz@g10code.com>
+
+ * mpi-cmp.c (gcry_mpi_cmp_ui): Rewritten; correctly handle case of
+ zero limbs in U.
+
+2005-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (gcry_mpi_randomize): Store random data in secure
+ memory if the given MPI is secure - not the other way around (argl).
+
+2005-04-23 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Don't assume the compiler will pre-process the .S
+ files. Some compilers, like those from HP and IBM, don't do
+ this. So, we use the same solution gnupg-1.4.0 does. Preprocess
+ first and then compile.
+
+ * hppa1.1/mpih-mul3.S: Add "level 1.1" directive to disable
+ warning about using PA-RISC1.1 opcodes.
+ * hppa1.1/mpih-mul2.S: Likewise.
+ * hppa1.1/mpih-mul1.S: Likewise.
+ * hppa1.1/udiv-qrnnd.S: Likewise.
+
+2005-02-16 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Rewritten, fixed memory
+ corruption.
+
+2005-02-06 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_get_ui, gcry_mpi_get_ui): New functions.
+
+2005-01-05 Werner Koch <wk@g10code.com>
+
+ * hppa1.1/udiv-qrnnd.S: Reverted change of 2004-03-02 but kept the
+ .align directive.
+
+2004-12-16 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Move entry for powerpc64
+ before generic powerpc. Suggested by Rafael Ãvila de Espíndola.
+
+2004-03-02 Werner Koch <wk@gnupg.org>
+
+ * hppa1.1/udiv-qrnnd.S: Alignment fix from Lamont Jones for
+ Debian. Taken from gnupg-1.3.
+
+ * longlong.h: Added PowerPC 64 bit code from GPM-4.1.2 but didn't
+ enable it yet. Some whitespace changes in HPPA to fix assembler
+ problems on HP-UX. From gnupg 1.3
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Better allocate
+ something even if NLIMBS is passed as 0.
+
+ * config.links: Updated system list to match gnupg 1.3.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h [M_DEBUG]: Removed this unused code.
+ (struct karatsuba_ctx): Added TSPACE_NLIMBS and TP_NLIMBS.
+ * mpiutil.c (_gcry_mpi_free_limb_space): Add arg NLIMBS and wipe
+ out the memory. Changed all callers.
+ * mpih-mul.c (_gcry_mpih_mul_karatsuba_case): Keep track of
+ allocated limbs.
+ * mpi-div.c (_gcry_mpi_tdiv_qr): Keep track of allocated limbs.
+ * mpi-mul.c (gcry_mpi_mul): Ditto.
+ * mpi-pow.c (gcry_mpi_powm): Ditto.
+
+ * Manifest: Empty new file. Also add Manifest files to all CPU
+ specific directories.
+ * Makefile.am: Added.
+
+ * mpiutil.c (gcry_mpi_randomize): Use gcry_create_nonce if WEAK
+ random has been requested.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * i386/mpih-rshift.S, i386/mpih-lshift.S: Use %dl and not %edx for
+ testb; this avoids an assembler warning.
+
+ * mpi-pow.c (gcry_mpi_powm): s/exp/expo/ to avoid shadowing warning.
+
+2003-08-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (SUFFIXES): New variable.
+ (.S.o, .S.lo, .S.obj): Rewritten.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * longlong.h (__clz_tab): Renamed to _gcry_clz_tab.
+ * mpi-bit.c (__clz_tab): Likewise.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): New argument BUFLEN to replace the
+ use of the intial value of NBYTES. Changed BUFFER to unsigned.
+ (gcry_mpi_print): Likewise.
+ (gcry_mpi_dump): New.
+ (_gcry_log_mpidump): Make use of gcry_mpi_dump.
+ (mpi_print): Removed.
+ (gcry_mpi_scan): Allocated mpi in secure memory when required.
+ (gcry_mpi_aprint): Changed BUFFER to unsigned char*.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * mpicoder.c: Used gcry_err* wrappers for libgpg-error symbols.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * mpi-add.c: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * mpi-bit.c: Likewise.
+ * mpi-cmp.c: Likewise.
+ * mpi-div.c: Likewise.
+ * mpi-gcd.c: Likewise.
+ * mpi-internal.h: Likewise.
+ * mpi-inv.c: Likewise.
+ * mpi-mpow.c: Likewise.
+ * mpi-mul.c: Likewise.
+ * mpi-pow.c: Likewise.
+ * mpi-scan.c: Likewise.
+ * mpicoder.c: Likewise.
+ * mpiutil.c: Likewise.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * mpicoder.c (gcry_mpi_scan): Adjust for libgpg-error.
+ (gcry_mpi_print): Likewise.
+ (gcry_mpi_aprint): Likewise.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * longlong.h, mpi-add.c, mpi-bit.c, mpi-cmp.c, mpi-div.c,
+ mpi-gcd.c, mpi-inline.c, mpi-inline.h, mpi-internal.h, mpi-inv.c,
+ mpi-mpow.c, mpi-mul.c, mpi-pow.c, mpi-scan.c, mpicoder.c,
+ mpih-div.c, mpih-mul.c, mpiutil.c, generic/mpi-asm-defs.h,
+ generic/mpih-add1.c, generic/mpih-lshift.c, generic/mpih-mul1.c,
+ generic/mpih-mul2.c, generic/mpih-mul3.c, generic/mpih-rshift.c,
+ generic/mpih-sub1.c, generic/udiv-w-sdiv.c, i386/syntax.h,
+ m68k/syntax.h, mips3/mpi-asm-defs.h, powerpc32/syntax.h: Edited
+ all preprocessor instructions to remove whitespace before the '#'.
+ This is not required by C89, but there are some compilers out
+ there that don't like it. Replaced any occurence of the now
+ deprecated type names with the new ones.
+
+2003-05-21 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Only try to allocate
+ memory in case the amount of bytes to allocate is non-zero.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_resize): Allocate secure memory, in case
+ bit zero of `flags' is set.
+
+ * mpi-add.c (gcry_mpi_sub): Simplify function; always use a
+ temporary variable now.
+
+2003-04-15 Werner Koch <wk@gnupg.org>
+
+ * longlong.h (umul_ppmm): Support SH3 and SH4. Thanks to
+ kazuya.s@jp.yokogawa.com.
+
+2003-04-02 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_print): Fixed testing against possible
+ uninitialized LEN. Valgrinded by Nikos Mavroyanopoulos.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * longlong.h: Removed some spaces between backslashes and newlines.
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ * mpi-mul.c (gcry_mpi_mul_2exp): New. This was declared in
+ gcrypt.h but only implemented as internal function. Noted by Timo
+ but a few minutes to late for today's release.
+
+ * Makefile.am (DISTCLEANFILES): Include mpi-asm-defs.h
+
+2002-09-18 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (.S.lo): Pass -DPIC. i386, PPC and Sparc code
+ require it. It worked for me because I am using the i586 code.
+
+2002-08-23 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (.S.lo): Fixed for libtool build with --disable-shared.
+
+2002-07-24 Werner Koch <wk@gnupg.org>
+
+ * longlong.h: Replaced all K&R multiline strings by ISO ones for
+ the sake of modern compilers. Suggested by Marco Parrone.
+
+2002-06-24 Werner Koch <wk@gnupg.org>
+
+ * mpiutil.c (gcry_mpi_swap): New.
+
+ * mpi-div.c (gcry_mpi_div): New.
+ (gcry_mpi_mod): New.
+ * mpi-inv.c (gcry_mpi_invm): New.
+
+ * mpicoder.c (do_get_buffer): Make sure that we allocate at least
+ one byte.
+
+2002-06-12 Werner Koch <wk@gnupg.org>
+
+ * hppa1.1/udiv-qrnnd.S: Changes for PIC by Randolph Chung.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * config.links: Chnage the way the mpi modules are determined.
+ * Makefile.am: Revamped to better handle modules
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of all files to the LGPL.
+
+2002-04-18 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): Don't use normalize on a NULL MPI.
+
+2002-03-20 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (mpi_read_from_buffer): Bail out on a zero length
+ buffer because we can't eventually do an malloc of this size.
+ Reported by Timo.
+
+2002-01-14 Werner Koch <wk@gnupg.org>
+
+ * mpi-inv.c (_gcry_mpi_invm): Typo fixes, noted by Carlo Perassi.
+
+2001-11-01 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): Allow to pass a nbytes as NULL or
+ with value 0 for format GCRY_FMT_SSH, so that the length is not
+ used for any checks, only the length stored in the bufer is used.
+ This is a nice format becuase we can just pass a buffer around and
+ don't need to care about its length.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * config.links: Changed the way the list of files to be
+ symlinked is returned.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * mpih-cmp.c: Removed and moved mpihelp_cmp to ..
+ * mpi-inline.h: .. here.
+
+ Major function renaming. All global functions are now prefixed
+ with _gcry_ or gcry_. Renamed also all mpihelp_ to just mpih_ so
+ that functions names are not getting to long an unreadable and for
+ better matching with the filenames.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (mpi_fromstr): Made static and assume that all input
+ is in hexformat.
+
+ Updated all CPU specific code with the one from GnuPG-1.0.5. This
+ is just a change of text formatting and the use of .label
+ instead of labels for hppa and pa7100.
+
+ * longlong.h: Fixes for ARM by Phil Blundell.
+
+2001-03-29 Werner Koch <wk@gnupg.org>
+
+ * mpi-mul.c (mpi_mul): Make sure that secret temporary results are
+ not stored in w. Suggested by Florian Weimer.
+
+ * config.links: Use i386 code for i386. According to tests by
+ Kevin Ryde the i586 code runs slow on i386 CPUs. Ditto for i786.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am: Removed mpi.h.
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h: Put limb_t definition in an ifdef.
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h, mpi.h: Changed the way they are called and
+ introduced DID_MPI_LIMP_TYPEDEF hack. Very ugly, should all be
+ revamped.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-11 Werner Koch <wk@gnupg.org>
+
+ * generic/mpi-asm-defs.h: New.
+ * mips3/mpi-asm-defs.h: New.
+ * config.links: Create a link to one of the above files.
+
+Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
+
+ * mpicoder.c (gcry_mpi_scan): Normalize the returned MPI.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * config.links: Support for powerpc--netbsd by Gabriel Rosenkoetter.
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * power/: Add all files from GMP for this CPU. Converted comments to
+ CPP comments because some ASes complain about ' in comments.
+
+ * config.links: Support for BSDI 4.x; by Wayne Chapeskie. Add support
+ for FreeBSD 5 and made the case stmt looking nicer; by Jun Kuriyama.
+ Add support for NetBSD.
+ (sparc8): Made the search path the same as sparc9
+ (sparc64-unknown-linux-gnu): use udiv module; by Adam Mitchell.
+
+ * Makefile.am: c/SFLAGS/ASFLAGS/. This has only been used by the
+ powerpc and actually never passed the -Wa,foo to the cc.
+
+ * mpih-div.c (mpihelp_divrem): The MPN_COPY_DECR copied one element
+ too many. This is a gmp2.0.2p9.txt patch.
+
+ * longlong.h (umul_ppmm): Fixes for ARM-4. By Sean MacLennan.
+
+ * mpi-internal.h (karatsuba_ctx): New.
+ * mpih-mul.c (mpihelp_release_karatsuba_ctx): New.
+ (mpihelp_mul_karatsuba_case): New.
+ (mpihelp_mul): Splitted to make use of the new functions.
+ * mpi-pow.c (mpi_powm): Make use of the new splitted function to avoid
+ multiple allocation of temporary memory during the karatsuba operations.
+ * mpi_mpow.c: Removed the unused Barrett code.
+
+2000-03-21 16:17:30 Werner Koch (wk@habibti.openit.de)
+
+ * config.links: Add support for FreeBSD 5.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (gcry_mpi_aprint): Now really returns the length.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * mpiutil.c: Removed all memory debugging code.
+
+ * mpicoder.c (gcry_mpi_aprint): New.
+
+ * Replaced all m_ memory functions by g10_ ones.
+
+Fri Dec 31 14:06:56 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpi-bit.c (gcry_mpi_get_nbits): New.
+
+ * mpiutil.c (mpi_set_secure): made static.
+ (gcry_mpi_get_flag): New.
+ (gcry_mpi_set_flag): New.
+ (gcry_mpi_clear_flag): New.
+ (mpi_set_opaque): renamed to gcry_mpi_set_opaque.
+ (mpi_get_opaque): renamed to gcry_mpi_get_opaque.
+
+Fri Dec 31 12:48:31 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (mpi_read_from_buffer): Made static.
+ (gcry_mpi_print): A buffer of NULL is now allowed to get the required
+ length back.
+ (mpi_get_keyid): Removed.
+ (mpi_print): Made static - should be removed.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * Makefile.am (INCLUDES): Add ../gcrypt.
+
+ * g10m.c : Removed.
+
+ * mpicoder.c (mpi_write): Removed.
+ (mpi_read): Removed.
+ (gcry_mpi_scan): New. Taken from ../gcrypt/mpiapi.c.
+ (gcry_mpi_print): Ditto.
+
+ * mpi-pow.c (mpi_powm): Renamed to ...
+ (gcry_mpi_powm): ... this.
+
+ * mpiutil.c (gcry_mpi_new): New as a wrapper around the old function.
+ Taken from ../gcrypt/mpiapi.c.
+ (gcry_mpi_snew): Ditto.
+ (gcry_mpi_release): Ditto.
+ (gcry_mpi_copy): Ditto.
+ (gcry_mpi_set): Ditto.
+ (gcry_mpi_set_ui): Ditto.
+ (gcry_mpi_cmp): Ditto.
+ (gcry_mpi_cmp_ui): Ditto.
+ (gcry_mpi_randomize): Ditto.
+
+ * mpicoder.c (mpi_print): Removed the nbit_info kludge.
+ * mpi-bits.c (mpi_get_nbits): Replaced the is_protected stuff by
+ checking whether it is an opaque mpi and then returns it's length
+ in bits.
+ * mpiutil.c (mpi_set_opaque): Changed the interface to take a number
+ of bits for the length. Adjusted all users.
+ (mpi_get_opaque): Ditto.
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (g10_log_mpidump): Add a temporary workaround
+
+ * mpih-mul.c (mpihelp_mul_n): s/m_is_ecure/g10_is_secure/
+
+ * mpiutil.c (mpi_alloc): Remved the debug mode because it has turned
+ out, that this feature was not very useful in the past. Use the
+ new alloc functions.
+ (mpi_alloc_secure): Ditto.
+ (mpi_alloc_limb_space): Ditto.
+ (mpi_free_limb_space): Ditto.
+ (mpi_resize): Ditto.
+ (mpi_free): Ditto.
+ (mpi_set_secure): Removed the debug stuff.
+ (mpi_set_opaque): Ditto.
+ (mpi_copy): Ditto.
+ (mpi_alloc_set_ui): Ditto.
+ (mpi_m_check): Use g10_ wrapper.
+
+Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * config.links: Add case label for DJGPP
+
+Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * Makefile.am: Use .s files as temporaries, disabled other .S rules.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * mpicoder.c (g10_log_mpidump): New.
+
+ * Makefile.am: Support for libtool.
+
+Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * mpi-bit.c (mpi_lshift_limbs,mpi_rshift_limbs): New.
+ * mpi-mpow.c (barrett_mulm): New but diabled.
+
+Tue Jun 1 16:01:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links (i[56]86*-*-freebsdelf*): New.
+
+Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links (sysdep.h): Not any more conditionally created.
+
+Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpiutil.c (mpi_alloc_like): New.
+
+Mon Apr 26 17:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpih-add.c, mpih-sub.c: Removed
+ * mpi-inline.c: New.
+ * mpi-inline.h: Make it usable by mpi-inline.c.
+
+Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpih-mul.c (mpihelp_mul_n): Fixed use of memory region.
+ (mpihelp_mul): Ditto.
+
+Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Explicit rules to invoke cpp on *.S
+
+Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links: Take advantage of the with_symbol_underscore macro.
+ Add support for freebsd 4.
+
+Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mips3/mpih-sub1.S: Removed left over junk in last line. (Should I
+ blame me or my editor?).
+
+Sat Feb 13 12:04:43 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Removed the +=. Add MPI_OPT_FLAGS.
+
+Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpi-cmp.c (mpi_cmp_ui): Normalized the arg.
+
+Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpi-bit.c (mpi_normalize): New.
+ (mpi_get_nbits): Normalize the MPI.
+ * mpi-bit.c (mpi_cmp): Normalize the MPI before the compare.
+
+
+Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links: Moved the case for powerpc*linux
+ * powerpcp32/*.S: Removed some underscores.
+
+Thu Nov 26 07:27:52 1998 Werner Koch <werner.koch@guug.de>
+
+ * config.links: Support for ppc with ELF
+ * powerpc32/syntax.h: New.
+ * powerpc32/*.S: Applied ELF patches (glibc patches)
+
+Tue Nov 10 19:31:37 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * power*/ : Started with stuff for PPC
+ * config.links: Some stuff for PPC.
+ * generic/udiv-w-sdiv.c: New but disabled.
+
+Tue Oct 27 12:37:46 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (freebsd): Fixes for FreeBSD 3.0
+
+Wed Oct 14 09:59:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (freebsd): ELF patches from Jun Kuriyama.
+
+Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free).
+
+Thu Sep 17 18:08:50 1998 Werner Koch (wk@(none))
+
+ * hppa1.1/udiv-qrnnd.S: Fix from Steffen Zahn for HPUX 10.20
+
+Thu Aug 6 16:39:28 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * mpi-bit.c (mpi_set_bytes): Removed.
+
+Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none))
+
+ * mpicoder.c (mpi_read_from_buffer): New.
+
+ * mpiutil.c (mpi_set_opaque): New.
+ (mpi_get_opaque): New.
+ (mpi_copy): Changed to support opauqe flag
+ (mpi_free): Ditto.
+
+Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpiutil.c (mpi_clear): Reset flags.
+ (mpi_set): Ditto.
+ (mpi_alloc_secure): Set flag to 1 and not ored the 1 in, tsss..
+
+Fri Jun 26 11:19:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpiutil.c (mpi_alloc): set nbits to 0.
+ (mpi_alloc_secure): Ditto.
+ (mpi_clear): Ditto.
+
+Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mips3/*.S: New
+
+Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: split mpih-shift into mpih-[lr]shift and
+ changed all implementations.
+ * mpi/alpha: add some new assembler stuff.
+
+Wed May 13 11:04:29 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: Add support for MIPS
+
+Thu Apr 9 11:31:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpicoder.c (mpi_get_secure_buffer): New.
+
+Wed Apr 8 09:44:33 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: Applied small fix from Ulf Möller.
+
+Mon Apr 6 12:38:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpicoder.c (mpi_get_buffer): Removed returned leading zeroes
+ and changed all callers.
+
+Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi-bit.c (mpi_clear_highbit): New.
+
+Mon Mar 2 19:29:00 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (DISTCLEANFILES): New
+
+Thu Feb 26 06:48:54 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (X86_BROKEN_ALIGN): Added for some systems.
+
+Mon Feb 23 12:21:40 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi/m68k/mpih-shift.S (Lspecial): Changed duplicate symbol.
+
+Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links : Add detection of m68k cpus
+
+
+ Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/grub-core/lib/libgcrypt/mpi/Makefile.am b/grub-core/lib/libgcrypt/mpi/Makefile.am
new file mode 100644
index 0000000..e900539
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/Makefile.am
@@ -0,0 +1,177 @@
+## Process this file with automake to produce Makefile.in
+# Copyright (C) 1992, 1999, 2000, 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# 1.5 leads to a combinatorial explosion due to all the conditionals
+# I was not able to build it with 64Megs - 1.6 fixes this.
+# not anymore required: AUTOMAKE_OPTIONS = 1.6
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+
+AM_ASFLAGS = $(MPI_SFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+
+EXTRA_DIST = Manifest config.links
+DISTCLEANFILES = mpi-asm-defs.h \
+ mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \
+ mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \
+ mpih-add1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c \
+ mpih-lshift.c mpih-rshift.c mpih-sub1.c \
+ sysdep.h mod-source-info.h
+
+# Beware: The following list is not a comment but grepped by
+# config.links to get the list of symlinked modules
+# Optional modules are marked with an O in the second column.
+#BEGIN_ASM_LIST
+# mpih-add1 C
+# mpih-sub1 C
+# mpih-mul1 C
+# mpih-mul2 C
+# mpih-mul3 C
+# mpih-lshift C
+# mpih-rshift C
+# udiv O
+# udiv-qrnnd O
+#END_ASM_LIST
+
+# Note: This function has not yet been implemented. There is only a dummy in
+# generic/
+# udiv-w-sdiv O
+
+# And we need to have conditionals for all modules because
+# we don't know whether they are .c or .S. Very ugly; I know.
+# Remember to define them all in configure.ac
+if MPI_MOD_ASM_MPIH_ADD1
+mpih_add1 = mpih-add1-asm.S
+else
+if MPI_MOD_C_MPIH_ADD1
+mpih_add1 = mpih-add1.c
+else
+mpih_add1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_SUB1
+mpih_sub1 = mpih-sub1-asm.S
+else
+if MPI_MOD_C_MPIH_SUB1
+mpih_sub1 = mpih-sub1.c
+else
+mpih_sub1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL1
+mpih_mul1 = mpih-mul1-asm.S
+else
+if MPI_MOD_C_MPIH_MUL1
+mpih_mul1 = mpih-mul1.c
+else
+mpih_mul1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL2
+mpih_mul2 = mpih-mul2-asm.S
+else
+if MPI_MOD_C_MPIH_MUL2
+mpih_mul2 = mpih-mul2.c
+else
+mpih_mul2 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL3
+mpih_mul3 = mpih-mul3-asm.S
+else
+if MPI_MOD_C_MPIH_MUL3
+mpih_mul3 = mpih-mul3.c
+else
+mpih_mul3 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_LSHIFT
+mpih_lshift = mpih-lshift-asm.S
+else
+if MPI_MOD_C_MPIH_LSHIFT
+mpih_lshift = mpih-lshift.c
+else
+mpih_lshift =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_RSHIFT
+mpih_rshift = mpih-rshift-asm.S
+else
+if MPI_MOD_C_MPIH_RSHIFT
+mpih_rshift = mpih-rshift.c
+else
+mpih_rshift =
+endif
+endif
+
+if MPI_MOD_ASM_UDIV
+udiv = udiv-asm.S
+else
+if MPI_MOD_C_UDIV
+udiv = udiv.c
+else
+udiv =
+endif
+endif
+
+if MPI_MOD_ASM_UDIV_QRNND
+udiv_qrnnd = udiv-qrnnd-asm.S
+else
+if MPI_MOD_C_UDIV_QRNND
+udiv_qrnnd = udiv-qrnnd.c
+else
+udiv_qrnnd =
+endif
+endif
+
+noinst_LTLIBRARIES = libmpi.la
+
+libmpi_la_LDFLAGS =
+nodist_libmpi_la_SOURCES = $(mpih_add1) $(mpih_sub1) $(mpih_mul1) \
+ $(mpih_mul2) $(mpih_mul3) $(mpih_lshift) $(mpih_rshift) \
+ $(udiv) $(udiv_qrnnd)
+libmpi_la_SOURCES = longlong.h \
+ mpi-add.c \
+ mpi-bit.c \
+ mpi-cmp.c \
+ mpi-div.c \
+ mpi-gcd.c \
+ mpi-internal.h \
+ mpi-inline.h \
+ mpi-inline.c \
+ mpi-inv.c \
+ mpi-mul.c \
+ mpi-mod.c \
+ mpi-pow.c \
+ mpi-mpow.c \
+ mpi-scan.c \
+ mpicoder.c \
+ mpih-div.c \
+ mpih-mul.c \
+ mpiutil.c \
+ ec.c
diff --git a/grub-core/lib/libgcrypt/mpi/Manifest b/grub-core/lib/libgcrypt/mpi/Manifest
new file mode 100644
index 0000000..3b0d673
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/Manifest
@@ -0,0 +1,41 @@
+# Manifest - checksums of the mpi directory
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Makefile.am
+config.links
+longlong.h
+mpi-add.c
+mpi-bit.c
+mpi-cmp.c
+mpi-div.c
+mpi-gcd.c
+mpi-inline.c
+mpi-inline.h
+mpi-internal.h
+mpi-inv.c
+mpi-mpow.c
+mpi-mul.c
+mpi-pow.c
+mpi-scan.c
+mpicoder.c
+mpih-div.c
+mpih-mul.c
+mpiutil.c
+$names$ iQCVAwUAP+LmfDEAnp832S/7AQKZJQQAkR/gQITUM+6Ygy9WAOAO17btyKAlCtGTXp5XSZ+J3X0o/rYneRdSCW89IJvwFRJjAOcFJd52MXs6ZVFF/RQBC8MvJzuQChbEzvihK8o2VgK34YWjU+6XH9sFgRMIgzkHs/51ZZxeQUOPy1XF7TyKB0WE7YBUVisFiRaqB1qGIOs==Z3qB
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/README b/grub-core/lib/libgcrypt/mpi/alpha/README
new file mode 100644
index 0000000..55c0a29
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/README
@@ -0,0 +1,53 @@
+This directory contains mpn functions optimized for DEC Alpha processors.
+
+RELEVANT OPTIMIZATION ISSUES
+
+EV4
+
+1. This chip has very limited store bandwidth. The on-chip L1 cache is
+write-through, and a cache line is transfered from the store buffer to the
+off-chip L2 in as much 15 cycles on most systems. This delay hurts
+mpn_add_n, mpn_sub_n, mpn_lshift, and mpn_rshift.
+
+2. Pairing is possible between memory instructions and integer arithmetic
+instructions.
+
+3. mulq and umulh is documented to have a latency of 23 cycles, but 2 of
+these cycles are pipelined. Thus, multiply instructions can be issued at a
+rate of one each 21nd cycle.
+
+EV5
+
+1. The memory bandwidth of this chip seems excellent, both for loads and
+stores. Even when the working set is larger than the on-chip L1 and L2
+caches, the perfromance remain almost unaffected.
+
+2. mulq has a measured latency of 13 cycles and an issue rate of 1 each 8th
+cycle. umulh has a measured latency of 15 cycles and an issue rate of 1
+each 10th cycle. But the exact timing is somewhat confusing.
+
+3. mpn_add_n. With 4-fold unrolling, we need 37 instructions, whereof 12
+ are memory operations. This will take at least
+ ceil(37/2) [dual issue] + 1 [taken branch] = 20 cycles
+ We have 12 memory cycles, plus 4 after-store conflict cycles, or 16 data
+ cache cycles, which should be completely hidden in the 20 issue cycles.
+ The computation is inherently serial, with these dependencies:
+ addq
+ / \
+ addq cmpult
+ | |
+ cmpult |
+ \ /
+ or
+ I.e., there is a 4 cycle path for each limb, making 16 cycles the absolute
+ minimum. We could replace the `or' with a cmoveq/cmovne, which would save
+ a cycle on EV5, but that might waste a cycle on EV4. Also, cmov takes 2
+ cycles.
+ addq
+ / \
+ addq cmpult
+ | \
+ cmpult -> cmovne
+
+STATUS
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/distfiles b/grub-core/lib/libgcrypt/mpi/alpha/distfiles
new file mode 100644
index 0000000..f2ab9fc
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/distfiles
@@ -0,0 +1,11 @@
+README
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+
+udiv-qrnnd.S
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S
new file mode 100644
index 0000000..50dbb2b
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S
@@ -0,0 +1,124 @@
+/* alpha add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ * Copyright (C) 1995, 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($16)
+ * mpi_ptr_t s1_ptr, ($17)
+ * mpi_ptr_t s2_ptr, ($18)
+ * mpi_size_t size) ($19)
+ */
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_add_n
+ .ent _gcry_mpih_add_n
+_gcry_mpih_add_n:
+ .frame $30,0,$26,0
+
+ ldq $3,0($17)
+ ldq $4,0($18)
+
+ subq $19,1,$19
+ and $19,4-1,$2 # number of limbs in first loop
+ bis $31,$31,$0
+ beq $2,.L0 # if multiple of 4 limbs, skip first loop
+
+ subq $19,$2,$19
+
+.Loop0: subq $2,1,$2
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ addq $17,8,$17
+ addq $18,8,$18
+ bis $5,$5,$3
+ bis $6,$6,$4
+ addq $16,8,$16
+ bne $2,.Loop0
+
+.L0: beq $19,.Lend
+
+ .align 3
+.Loop: subq $19,4,$19
+
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ ldq $3,16($17)
+ addq $6,$0,$6
+ ldq $4,16($18)
+ cmpult $6,$0,$1
+ addq $5,$6,$6
+ cmpult $6,$5,$0
+ stq $6,8($16)
+ or $0,$1,$0
+
+ ldq $5,24($17)
+ addq $4,$0,$4
+ ldq $6,24($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,16($16)
+ or $0,$1,$0
+
+ ldq $3,32($17)
+ addq $6,$0,$6
+ ldq $4,32($18)
+ cmpult $6,$0,$1
+ addq $5,$6,$6
+ cmpult $6,$5,$0
+ stq $6,24($16)
+ or $0,$1,$0
+
+ addq $17,32,$17
+ addq $18,32,$18
+ addq $16,32,$16
+ bne $19,.Loop
+
+.Lend: addq $4,$0,$4
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_add_n
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S
new file mode 100644
index 0000000..ded4b15
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S
@@ -0,0 +1,122 @@
+/* alpha - left shift
+ *
+ * Copyright (C) 1994, 1995, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (r16)
+ * mpi_ptr_t up, (r17)
+ * mpi_size_t usize, (r18)
+ * unsigned cnt) (r19)
+ *
+ * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
+ * it would take 4 cycles/limb. It should be possible to get down to 3
+ * cycles/limb since both ldq and stq can be paired with the other used
+ * instructions. But there are many restrictions in the 21064 pipeline that
+ * makes it hard, if not impossible, to get down to 3 cycles/limb:
+ *
+ * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
+ * 2. Only aligned instruction pairs can be paired.
+ * 3. The store buffer or silo might not be able to deal with the bandwidth.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_lshift
+ .ent _gcry_mpih_lshift
+_gcry_mpih_lshift:
+ .frame $30,0,$26,0
+
+ s8addq $18,$17,$17 # make r17 point at end of s1
+ ldq $4,-8($17) # load first limb
+ subq $17,8,$17
+ subq $31,$19,$7
+ s8addq $18,$16,$16 # make r16 point at end of RES
+ subq $18,1,$18
+ and $18,4-1,$20 # number of limbs in first loop
+ srl $4,$7,$0 # compute function result
+
+ beq $20,.L0
+ subq $18,$20,$18
+
+ .align 3
+.Loop0:
+ ldq $3,-8($17)
+ subq $16,8,$16
+ subq $17,8,$17
+ subq $20,1,$20
+ sll $4,$19,$5
+ srl $3,$7,$6
+ bis $3,$3,$4
+ bis $5,$6,$8
+ stq $8,0($16)
+ bne $20,.Loop0
+
+.L0: beq $18,.Lend
+
+ .align 3
+.Loop: ldq $3,-8($17)
+ subq $16,32,$16
+ subq $18,4,$18
+ sll $4,$19,$5
+ srl $3,$7,$6
+
+ ldq $4,-16($17)
+ sll $3,$19,$1
+ bis $5,$6,$8
+ stq $8,24($16)
+ srl $4,$7,$2
+
+ ldq $3,-24($17)
+ sll $4,$19,$5
+ bis $1,$2,$8
+ stq $8,16($16)
+ srl $3,$7,$6
+
+ ldq $4,-32($17)
+ sll $3,$19,$1
+ bis $5,$6,$8
+ stq $8,8($16)
+ srl $4,$7,$2
+
+ subq $17,32,$17
+ bis $1,$2,$8
+ stq $8,0($16)
+
+ bgt $18,.Loop
+
+.Lend: sll $4,$19,$8
+ stq $8,-8($16)
+ ret $31,($26),1
+ .end _gcry_mpih_lshift
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S
new file mode 100644
index 0000000..cd91b10
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S
@@ -0,0 +1,90 @@
+/* Alpha 21064 mpih-mul1.S -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_size_t s1_size, (r18)
+ * mpi_limb_t s2_limb) (r19)
+ *
+ * This code runs at 42 cycles/limb on the EV4 and 18 cycles/limb on the EV5.
+ *
+ * To improve performance for long multiplications, we would use
+ * 'fetch' for S1 and 'fetch_m' for RES. It's not obvious how to use
+ * these instructions without slowing down the general code: 1. We can
+ * only have two prefetches in operation at any time in the Alpha
+ * architecture. 2. There will seldom be any special alignment
+ * between RES_PTR and S1_PTR. Maybe we can simply divide the current
+ * loop into an inner and outer loop, having the inner loop handle
+ * exactly one prefetch block?
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_mul_1
+ .ent _gcry_mpih_mul_1 2
+_gcry_mpih_mul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ bic $31,$31,$4 # clear cy_limb
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,Lend1 # jump if size was == 1
+ ldq $2,8($17) # $2 = s1_limb
+ subq $18,1,$18 # size--
+ stq $3,0($16)
+ beq $18,Lend2 # jump if size was == 2
+
+ .align 3
+Loop: mulq $2,$19,$3 # $3 = prod_low
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,16($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ stq $3,8($16)
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $16,8,$16 # res_ptr++
+ bne $18,Loop
+
+Lend2: mulq $2,$19,$3 # $3 = prod_low
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ stq $3,8($16)
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+Lend1: stq $3,0($16)
+ ret $31,($26),1
+
+ .end _gcry_mpih_mul_1
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S
new file mode 100644
index 0000000..5eb6b98
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S
@@ -0,0 +1,97 @@
+/* Alpha 21064 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_size_t s1_size, (r18)
+ * mpi_limb_t s2_limb) (r19)
+ *
+ * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
+ */
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_addmul_1
+ .ent _gcry_mpih_addmul_1 2
+_gcry_mpih_addmul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,.Lend1 # jump if size was == 1
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ addq $5,$3,$3
+ cmpult $3,$5,$4
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ beq $18,.Lend2 # jump if size was == 2
+
+ .align 3
+.Loop: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ addq $5,$0,$0 # combine carries
+ bne $18,.Loop
+
+.Lend2: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $5,$0,$0 # combine carries
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+.Lend1: addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $0,$5,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_addmul_1
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S
new file mode 100644
index 0000000..7d5d2af
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S
@@ -0,0 +1,95 @@
+/* Alpha 21064 submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r16 )
+ * mpi_ptr_t s1_ptr, (r17 )
+ * mpi_size_t s1_size, (r18 )
+ * mpi_limb_t s2_limb) (r19 )
+ *
+ * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_submul_1
+ .ent _gcry_mpih_submul_1 2
+_gcry_mpih_submul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,.Lend1 # jump if size was == 1
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ subq $5,$3,$3
+ cmpult $5,$3,$4
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ beq $18,.Lend2 # jump if size was == 2
+
+ .align 3
+.Loop: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ addq $5,$0,$0 # combine carries
+ bne $18,.Loop
+
+.Lend2: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $5,$0,$0 # combine carries
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+.Lend1: subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $0,$5,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_submul_1
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S
new file mode 100644
index 0000000..f0c9814
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S
@@ -0,0 +1,118 @@
+/* alpha rshift
+ * Copyright (C) 1994, 1995, 1998, 1999,
+ * 2000, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (r16)
+ * mpi_ptr_t up, (r17)
+ * mpi_size_t usize, (r18)
+ * unsigned cnt) (r19)
+ *
+ * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
+ * it would take 4 cycles/limb. It should be possible to get down to 3
+ * cycles/limb since both ldq and stq can be paired with the other used
+ * instructions. But there are many restrictions in the 21064 pipeline that
+ * makes it hard, if not impossible, to get down to 3 cycles/limb:
+ *
+ * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
+ * 2. Only aligned instruction pairs can be paired.
+ * 3. The store buffer or silo might not be able to deal with the bandwidth.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_rshift
+ .ent _gcry_mpih_rshift
+_gcry_mpih_rshift:
+ .frame $30,0,$26,0
+
+ ldq $4,0($17) # load first limb
+ addq $17,8,$17
+ subq $31,$19,$7
+ subq $18,1,$18
+ and $18,4-1,$20 # number of limbs in first loop
+ sll $4,$7,$0 # compute function result
+
+ beq $20,.R0
+ subq $18,$20,$18
+
+ .align 3
+.Roop0:
+ ldq $3,0($17)
+ addq $16,8,$16
+ addq $17,8,$17
+ subq $20,1,$20
+ srl $4,$19,$5
+ sll $3,$7,$6
+ bis $3,$3,$4
+ bis $5,$6,$8
+ stq $8,-8($16)
+ bne $20,.Roop0
+
+.R0: beq $18,.Rend
+
+ .align 3
+.Roop: ldq $3,0($17)
+ addq $16,32,$16
+ subq $18,4,$18
+ srl $4,$19,$5
+ sll $3,$7,$6
+
+ ldq $4,8($17)
+ srl $3,$19,$1
+ bis $5,$6,$8
+ stq $8,-32($16)
+ sll $4,$7,$2
+
+ ldq $3,16($17)
+ srl $4,$19,$5
+ bis $1,$2,$8
+ stq $8,-24($16)
+ sll $3,$7,$6
+
+ ldq $4,24($17)
+ srl $3,$19,$1
+ bis $5,$6,$8
+ stq $8,-16($16)
+ sll $4,$7,$2
+
+ addq $17,32,$17
+ bis $1,$2,$8
+ stq $8,-8($16)
+
+ bgt $18,.Roop
+
+.Rend: srl $4,$19,$8
+ stq $8,0($16)
+ ret $31,($26),1
+ .end _gcry_mpih_rshift
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S
new file mode 100644
index 0000000..9a64446
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S
@@ -0,0 +1,124 @@
+/* Alpha sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ * Copyright (C) 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_ptr_t s2_ptr, (r18)
+ * mpi_size_t size) (r19)
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_sub_n
+ .ent _gcry_mpih_sub_n
+_gcry_mpih_sub_n:
+ .frame $30,0,$26,0
+
+ ldq $3,0($17)
+ ldq $4,0($18)
+
+ subq $19,1,$19
+ and $19,4-1,$2 # number of limbs in first loop
+ bis $31,$31,$0
+ beq $2,.L0 # if multiple of 4 limbs, skip first loop
+
+ subq $19,$2,$19
+
+.Loop0: subq $2,1,$2
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ addq $17,8,$17
+ addq $18,8,$18
+ bis $5,$5,$3
+ bis $6,$6,$4
+ addq $16,8,$16
+ bne $2,.Loop0
+
+.L0: beq $19,.Lend
+
+ .align 3
+.Loop: subq $19,4,$19
+
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ ldq $3,16($17)
+ addq $6,$0,$6
+ ldq $4,16($18)
+ cmpult $6,$0,$1
+ subq $5,$6,$6
+ cmpult $5,$6,$0
+ stq $6,8($16)
+ or $0,$1,$0
+
+ ldq $5,24($17)
+ addq $4,$0,$4
+ ldq $6,24($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,16($16)
+ or $0,$1,$0
+
+ ldq $3,32($17)
+ addq $6,$0,$6
+ ldq $4,32($18)
+ cmpult $6,$0,$1
+ subq $5,$6,$6
+ cmpult $5,$6,$0
+ stq $6,24($16)
+ or $0,$1,$0
+
+ addq $17,32,$17
+ addq $18,32,$18
+ addq $16,32,$16
+ bne $19,.Loop
+
+.Lend: addq $4,$0,$4
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_sub_n
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S b/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S
new file mode 100644
index 0000000..dd0c52d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S
@@ -0,0 +1,159 @@
+/* Alpha 21064 __udiv_qrnnd
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __udiv_qrnnd
+ .ent __udiv_qrnnd
+__udiv_qrnnd:
+ .frame $30,0,$26,0
+ .prologue 0
+#define cnt $2
+#define tmp $3
+#define rem_ptr $16
+#define n1 $17
+#define n0 $18
+#define d $19
+#define qb $20
+
+ ldiq cnt,16
+ blt d,.Largedivisor
+
+.Loop1: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,.Loop1
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+.Largedivisor:
+ and n0,1,$4
+
+ srl n0,1,n0
+ sll n1,63,tmp
+ or tmp,n0,n0
+ srl n1,1,n1
+
+ and d,1,$6
+ srl d,1,$5
+ addq $5,$6,$5
+
+.Loop2: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,.Loop2
+
+ addq n1,n1,n1
+ addq $4,n1,n1
+ bne $6,.LOdd
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+.LOdd:
+ /* q' in n0. r' in n1 */
+ addq n1,n0,n1
+ cmpult n1,n0,tmp # tmp := carry from addq
+ beq tmp,.LLp6
+ addq n0,1,n0
+ subq n1,d,n1
+.LLp6: cmpult n1,d,tmp
+ bne tmp,.LLp7
+ addq n0,1,n0
+ subq n1,d,n1
+.LLp7:
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+ .end __udiv_qrnnd
diff --git a/grub-core/lib/libgcrypt/mpi/amd64/distfiles b/grub-core/lib/libgcrypt/mpi/amd64/distfiles
new file mode 100644
index 0000000..e664c8d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/amd64/distfiles
@@ -0,0 +1,7 @@
+mpih-add1.S
+mpih-lshift.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-rshift.S
+mpih-sub1.S
diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S
new file mode 100644
index 0000000..f0ec89c
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S
@@ -0,0 +1,63 @@
+/* AMD64 (x86_64) add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, rdi
+ * mpi_ptr_t s1_ptr, rsi
+ * mpi_ptr_t s2_ptr, rdx
+ * mpi_size_t size) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ leaq (%rsi,%rcx,8), %rsi
+ leaq (%rdi,%rcx,8), %rdi
+ leaq (%rdx,%rcx,8), %rdx
+ negq %rcx
+ xorl %eax, %eax /* clear cy */
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rcx,8), %rax
+ movq (%rdx,%rcx,8), %r10
+ adcq %r10, %rax
+ movq %rax, (%rdi,%rcx,8)
+ incq %rcx
+ jne .Loop
+
+ movq %rcx, %rax /* zero %rax */
+ adcq %rax, %rax
+ ret
+ \ No newline at end of file
diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S
new file mode 100644
index 0000000..e87dd1a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S
@@ -0,0 +1,77 @@
+/* AMD64 (x86_64) lshift -- Left shift a limb vector and store
+ * result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, rdi
+ * mpi_ptr_t up, rsi
+ * mpi_size_t usize, rdx
+ * unsigned cnt) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+ movq -8(%rsi,%rdx,8), %mm7
+ movd %ecx, %mm1
+ movl $64, %eax
+ subl %ecx, %eax
+ movd %eax, %mm0
+ movq %mm7, %mm3
+ psrlq %mm0, %mm7
+ movd %mm7, %rax
+ subq $2, %rdx
+ jl .Lendo
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rdx,8), %mm6
+ movq %mm6, %mm2
+ psrlq %mm0, %mm6
+ psllq %mm1, %mm3
+ por %mm6, %mm3
+ movq %mm3, 8(%rdi,%rdx,8)
+ je .Lende
+ movq -8(%rsi,%rdx,8), %mm7
+ movq %mm7, %mm3
+ psrlq %mm0, %mm7
+ psllq %mm1, %mm2
+ por %mm7, %mm2
+ movq %mm2, (%rdi,%rdx,8)
+ subq $2, %rdx
+ jge .Loop
+
+.Lendo: movq %mm3, %mm2
+.Lende: psllq %mm1, %mm2
+ movq %mm2, (%rdi)
+ emms
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S
new file mode 100644
index 0000000..54b0ab4
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S
@@ -0,0 +1,65 @@
+/* AMD64 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+
+
+ TEXT
+ ALIGN(5)
+ .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ movq %rdx, %r11
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+
+.Loop: movq (%rsi,%r11,8), %rax
+ mulq %rcx
+ addq %r8, %rax
+ movl $0, %r8d
+ adcq %rdx, %r8
+ movq %rax, (%rdi,%r11,8)
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S
new file mode 100644
index 0000000..1180f76
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S
@@ -0,0 +1,107 @@
+/* AMD64 addmul2 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_2( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+ /* i80386 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+ TEXT
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+ movq %rdx, %r11
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+ xorl %r10d, %r10d
+
+ ALIGN(3) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%r11,8), %rax
+ mulq %rcx
+ addq (%rdi,%r11,8), %rax
+ adcq %r10, %rdx
+ addq %r8, %rax
+ movq %r10, %r8
+ movq %rax, (%rdi,%r11,8)
+ adcq %rdx, %r8
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S
new file mode 100644
index 0000000..4d458a7
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S
@@ -0,0 +1,66 @@
+/* AMD64 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+ TEXT
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ movq %rdx, %r11
+ leaq (%rsi,%r11,8), %rsi
+ leaq (%rdi,%r11,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+
+ ALIGN(3) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%r11,8), %rax
+ movq (%rdi,%r11,8), %r10
+ mulq %rcx
+ subq %r8, %r10
+ movl $0, %r8d
+ adcl %r8d, %r8d
+ subq %rax, %r10
+ adcq %rdx, %r8
+ movq %r10, (%rdi,%r11,8)
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S
new file mode 100644
index 0000000..4cfc8f6
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S
@@ -0,0 +1,80 @@
+/* AMD64 (x86_64) rshift -- Right shift a limb vector and store
+ * result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, rdi
+ * mpi_ptr_t up, rsi
+ * mpi_size_t usize, rdx
+ * unsigned cnt) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ movq (%rsi), %mm7
+ movd %ecx, %mm1
+ movl $64, %eax
+ subl %ecx, %eax
+ movd %eax, %mm0
+ movq %mm7, %mm3
+ psllq %mm0, %mm7
+ movd %mm7, %rax
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %rdx
+ addq $2, %rdx
+ jg .Lendo
+
+ ALIGN(8) /* minimal alignment for claimed speed */
+.Loop: movq -8(%rsi,%rdx,8), %mm6
+ movq %mm6, %mm2
+ psllq %mm0, %mm6
+ psrlq %mm1, %mm3
+ por %mm6, %mm3
+ movq %mm3, -16(%rdi,%rdx,8)
+ je .Lende
+ movq (%rsi,%rdx,8), %mm7
+ movq %mm7, %mm3
+ psllq %mm0, %mm7
+ psrlq %mm1, %mm2
+ por %mm7, %mm2
+ movq %mm2, -8(%rdi,%rdx,8)
+ addq $2, %rdx
+ jle .Loop
+
+.Lendo: movq %mm3, %mm2
+.Lende: psrlq %mm1, %mm2
+ movq %mm2, -8(%rdi)
+ emms
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S
new file mode 100644
index 0000000..b3609b0
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S
@@ -0,0 +1,61 @@
+/* AMD64 (x86_64) sub_n -- Subtract two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, rdi
+ * mpi_ptr_t s1_ptr, rsi
+ * mpi_ptr_t s2_ptr, rdx
+ * mpi_size_t size) rcx
+ */
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+ leaq (%rsi,%rcx,8), %rsi
+ leaq (%rdi,%rcx,8), %rdi
+ leaq (%rdx,%rcx,8), %rdx
+ negq %rcx
+ xorl %eax, %eax /* clear cy */
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rcx,8), %rax
+ movq (%rdx,%rcx,8), %r10
+ sbbq %r10, %rax
+ movq %rax, (%rdi,%rcx,8)
+ incq %rcx
+ jne .Loop
+
+ movq %rcx, %rax /* zero %rax */
+ adcq %rax, %rax
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/config.links b/grub-core/lib/libgcrypt/mpi/config.links
new file mode 100644
index 0000000..7e910ee
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/config.links
@@ -0,0 +1,360 @@
+# config.links - helper for ../configure -*- mode: sh -*-
+# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+# sourced by ../configure to get the list of files to link
+# this should set $mpi_ln_list.
+# Note: this is called from the above directory.
+
+mpi_sflags=
+mpi_extra_modules=
+
+test -d ./mpi || mkdir ./mpi
+
+# We grep the list of modules from the Makefile so that
+# we don't need to maintain them here.
+mpi_standard_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
+ if( $3 != "O" ) print $2 }' $srcdir/mpi/Makefile.am`
+mpi_optional_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
+ if( $3 == "O" ) print $2 }' $srcdir/mpi/Makefile.am`
+
+
+echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
+echo "/* Host: ${host} */" >>./mpi/asm-syntax.h
+
+if test "$try_asm_modules" = "yes" ; then
+case "${host}" in
+ powerpc-apple-darwin* | \
+ i[34567]86*-*-openbsd[12]* | \
+ i[34567]86*-*-openbsd3.[0123]*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ i[3467]86*-*-openbsd* | \
+ i[3467]86*-*-freebsd*-elf | \
+ i[3467]86*-*-freebsd[3-9]* | \
+ i[3467]86*-*-freebsdelf* | \
+ i[3467]86*-*-netbsd* | \
+ i[3467]86*-*-k*bsd*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i586*-*-openbsd* | \
+ i586*-*-freebsd*-elf | \
+ i586*-*-freebsd[3-9]* | \
+ i586*-*-freebsdelf* | \
+ i586*-*-netbsd* | \
+ i586*-*-k*bsd* | \
+ pentium-*-netbsd* | \
+ pentiumpro-*-netbsd*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ ;;
+ i[34]86*-*-bsdi4*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i[3467]86*-*-linuxaout* | \
+ i[3467]86*-*-linuxoldld* | \
+ i[3467]86*-*-*bsd*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i586*-*-linuxaout* | \
+ i586*-*-linuxoldld* | \
+ i586*-*-*bsd*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ ;;
+ i[3467]86*-msdosdjgpp* | \
+ i[34]86*-apple-darwin*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i586*-msdosdjgpp* | \
+ i[567]86*-apple-darwin*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ ;;
+ i[3467]86*-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i586*-*-* | \
+ pentium-*-* | \
+ pentiumpro-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ ;;
+ x86_64-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="amd64"
+ ;;
+ alpha*-*-*)
+ echo '/* configured for alpha */' >>./mpi/asm-syntax.h
+ path="alpha"
+ mpi_extra_modules="udiv-qrnnd"
+ ;;
+ hppa7000*-*-*)
+ echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h
+ path="hppa1.1 hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ ;;
+ hppa1.0*-*-*)
+ echo '/* configured for HPPA 1.0 */' >>./mpi/asm-syntax.h
+ path="hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ ;;
+ hppa*-*-*) # assume pa7100
+ echo '/* configured for HPPA (pa7100) */' >>./mpi/asm-syntax.h
+ path="pa7100 hppa1.1 hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ ;;
+ sparc64-*-linux-gnu)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ sparc64-sun-solaris2*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*)
+ # There are no sparc64 assembler modules that work on the
+ # *BSDs, so use the generic C functions.
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ sparc64*-*-*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ sparc9*-*-* | \
+ ultrasparc*-*-* )
+ echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h
+ path="sparc32v8 sparc32"
+ ;;
+ sparc8*-*-* | \
+ microsparc*-*-*)
+ echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h
+ path="sparc32v8 sparc32"
+ ;;
+ supersparc*-*-*)
+ echo '/* configured for supersparc */' >>./mpi/asm-syntax.h
+ path="supersparc sparc32v8 sparc32"
+ mpi_extra_modules="udiv"
+ ;;
+ sparc*-*-*)
+ echo '/* configured for sparc */' >>./mpi/asm-syntax.h
+ path="sparc32"
+ mpi_extra_modules="udiv"
+ ;;
+ mips[34]*-*-* | \
+ mips*-*-irix6*)
+ echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h
+ path="mips3"
+ ;;
+ mips*-*-*)
+ echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h
+ path="mips2"
+ ;;
+
+ # Motorola 68k configurations. Let m68k mean 68020-68040.
+ # mc68000 or mc68060 configurations need to be specified explicitly
+ m680[234]0*-*-linuxaout* | \
+ m68k*-*-linuxaout*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68020 m68k"
+ ;;
+ m68060*-*-linuxaout*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k"
+ ;;
+ m680[234]0*-*-linux* | \
+ m68k*-*-linux*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ ;;
+ m68060*-*-linux*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k"
+ ;;
+ m68k-atari-mint)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68020 m68k"
+ ;;
+ m68000*-*-* | \
+ m68060*-*-*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68000"
+ ;;
+ m680[234]0*-*-* | \
+ m68k*-*-*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68020 m68k"
+ ;;
+
+ powerpc*-*-netbsd* | powerpc*-*-openbsd*)
+ echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ ;;
+
+ ppc620-*-* | \
+ powerpc64*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc64"
+ ;;
+ powerpc*-*-linux*)
+ echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
+ path="powerpc32"
+ ;;
+
+ rs6000-*-aix[456789]* | \
+ rs6000-*-aix3.2.[456789])
+ mpi_sflags="-Wa,-mpwr"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ ;;
+ rs6000-*-* | \
+ power-*-* | \
+ power2-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ ;;
+ powerpc-ibm-aix4.2.* )
+ # I am not sure about this one but a machine identified by
+ # powerpc-ibm-aix4.2.1.0 cannot use the powerpc32 code.
+ mpi_sflags="-Wa,-mpwr"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ ;;
+ ppc601-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="power powerpc32"
+ ;;
+ ppc60[234]*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ ;;
+ powerpc*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ ;;
+ *)
+ echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+esac
+else
+ echo '/* Assembler modules disabled on request */' >>./mpi/asm-syntax.h
+ path=""
+fi
+
+
+# Make sysdep.h
+echo '/* created by config.links - do not edit */' >./mpi/sysdep.h
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+ cat <<EOF >>./mpi/sysdep.h
+#if __STDC__
+#define C_SYMBOL_NAME(name) _##name
+#else
+#define C_SYMBOL_NAME(name) _/**/name
+#endif
+EOF
+else
+ cat <<EOF >>./mpi/sysdep.h
+#define C_SYMBOL_NAME(name) name
+EOF
+fi
+
+
+# Figure the required modules out
+mpi_required_modules=$mpi_standard_modules
+if test "$mpi_extra_modules" != ""; then
+ for fn in $mpi_extra_modules; do
+ for i in $mpi_optional_modules; do
+ if test "$fn" = "$i" ; then
+ mpi_required_modules="$mpi_required_modules $fn"
+ fi
+ done
+ done
+fi
+
+# Try to get file to link from the assembler subdirectory and
+# if this fails get it from the generic subdirectory.
+mpi_ln_list=
+mpi_mod_list=
+path=`echo "$mpi_extra_path $path generic" | tr ':' ' '`
+echo '/* Created by config.links - do not edit */' >./mpi/mod-source-info.h
+echo "/* Host: ${host} */" >>./mpi/mod-source-info.h
+echo "static char mod_source_info[] =" >>./mpi/mod-source-info.h
+for fn in $mpi_required_modules ; do
+ fnu=`echo $fn | sed 's/-/_/g'`
+ eval mpi_mod_c_${fnu}=no
+ eval mpi_mod_asm_${fnu}=no
+ for dir in $path ; do
+ rm -f $srcdir/mpi/$fn.[Sc]
+ if test -f $srcdir/mpi/$dir/$fn.S ; then
+ echo " \":$dir/$fn.S\"" >>./mpi/mod-source-info.h
+ mpi_ln_list="$mpi_ln_list mpi/$fn-asm.S:mpi/$dir/$fn.S"
+ eval mpi_mod_asm_${fnu}=yes
+ mpi_mod_list="$mpi_mod_list $fn"
+ break;
+ elif test -f $srcdir/mpi/$dir/$fn.c ; then
+ echo " \":$dir/$fn.c\"" >>./mpi/mod-source-info.h
+ mpi_ln_list="$mpi_ln_list mpi/$fn.c:mpi/$dir/$fn.c"
+ eval mpi_mod_c_${fnu}=yes
+ mpi_mod_list="$mpi_mod_list $fn"
+ break;
+ fi
+ done
+done
+echo " ;" >>./mpi/mod-source-info.h
+
+# Same thing for the file which defines the limb size
+path=`echo "$path generic" | tr ':' ' '`
+for dir in $path ; do
+ rm -f $srcdir/mpi/mpi-asm-defs.h
+ if test -f $srcdir/mpi/$dir/mpi-asm-defs.h ; then
+ mpi_ln_list="$mpi_ln_list mpi/mpi-asm-defs.h:mpi/$dir/mpi-asm-defs.h"
+ break;
+ fi
+done
diff --git a/grub-core/lib/libgcrypt/mpi/ec.c b/grub-core/lib/libgcrypt/mpi/ec.c
new file mode 100644
index 0000000..e325358
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/ec.c
@@ -0,0 +1,708 @@
+/* ec.c - Elliptic Curve functions
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+#define point_init(a) _gcry_mpi_ec_point_init ((a))
+#define point_free(a) _gcry_mpi_ec_point_free ((a))
+
+
+/* Object to represent a point in projective coordinates. */
+/* Currently defined in mpi.h */
+
+/* This context is used with all our EC functions. */
+struct mpi_ec_ctx_s
+{
+ /* Domain parameters. */
+ gcry_mpi_t p; /* Prime specifying the field GF(p). */
+ gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */
+
+ int a_is_pminus3; /* True if A = P - 3. */
+
+ /* Some often used constants. */
+ gcry_mpi_t one;
+ gcry_mpi_t two;
+ gcry_mpi_t three;
+ gcry_mpi_t four;
+ gcry_mpi_t eight;
+ gcry_mpi_t two_inv_p;
+
+ /* Scratch variables. */
+ gcry_mpi_t scratch[11];
+
+ /* Helper for fast reduction. */
+/* int nist_nbits; /\* If this is a NIST curve, the number of bits. *\/ */
+/* gcry_mpi_t s[10]; */
+/* gcry_mpi_t c; */
+
+};
+
+
+
+/* Initialized a point object. gcry_mpi_ec_point_free shall be used
+ to release this object. */
+void
+_gcry_mpi_ec_point_init (mpi_point_t *p)
+{
+ p->x = mpi_new (0);
+ p->y = mpi_new (0);
+ p->z = mpi_new (0);
+}
+
+
+/* Release a point object. */
+void
+_gcry_mpi_ec_point_free (mpi_point_t *p)
+{
+ mpi_free (p->x); p->x = NULL;
+ mpi_free (p->y); p->y = NULL;
+ mpi_free (p->z); p->z = NULL;
+}
+
+/* Set the value from S into D. */
+static void
+point_set (mpi_point_t *d, mpi_point_t *s)
+{
+ mpi_set (d->x, s->x);
+ mpi_set (d->y, s->y);
+ mpi_set (d->z, s->z);
+}
+
+
+
+static void
+ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_addm (w, u, v, ctx->p);
+}
+
+static void
+ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_subm (w, u, v, ctx->p);
+}
+
+static void
+ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+#if 0
+ /* NOTE: This code works only for limb sizes of 32 bit. */
+ mpi_limb_t *wp, *sp;
+
+ if (ctx->nist_nbits == 192)
+ {
+ mpi_mul (w, u, v);
+ mpi_resize (w, 12);
+ wp = w->d;
+
+ sp = ctx->s[0]->d;
+ sp[0*2+0] = wp[0*2+0];
+ sp[0*2+1] = wp[0*2+1];
+ sp[1*2+0] = wp[1*2+0];
+ sp[1*2+1] = wp[1*2+1];
+ sp[2*2+0] = wp[2*2+0];
+ sp[2*2+1] = wp[2*2+1];
+
+ sp = ctx->s[1]->d;
+ sp[0*2+0] = wp[3*2+0];
+ sp[0*2+1] = wp[3*2+1];
+ sp[1*2+0] = wp[3*2+0];
+ sp[1*2+1] = wp[3*2+1];
+ sp[2*2+0] = 0;
+ sp[2*2+1] = 0;
+
+ sp = ctx->s[2]->d;
+ sp[0*2+0] = 0;
+ sp[0*2+1] = 0;
+ sp[1*2+0] = wp[4*2+0];
+ sp[1*2+1] = wp[4*2+1];
+ sp[2*2+0] = wp[4*2+0];
+ sp[2*2+1] = wp[4*2+1];
+
+ sp = ctx->s[3]->d;
+ sp[0*2+0] = wp[5*2+0];
+ sp[0*2+1] = wp[5*2+1];
+ sp[1*2+0] = wp[5*2+0];
+ sp[1*2+1] = wp[5*2+1];
+ sp[2*2+0] = wp[5*2+0];
+ sp[2*2+1] = wp[5*2+1];
+
+ ctx->s[0]->nlimbs = 6;
+ ctx->s[1]->nlimbs = 6;
+ ctx->s[2]->nlimbs = 6;
+ ctx->s[3]->nlimbs = 6;
+
+ mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
+ mpi_add (ctx->c, ctx->c, ctx->s[2]);
+ mpi_add (ctx->c, ctx->c, ctx->s[3]);
+
+ while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
+ mpi_sub ( ctx->c, ctx->c, ctx->p );
+ mpi_set (w, ctx->c);
+ }
+ else if (ctx->nist_nbits == 384)
+ {
+ int i;
+ mpi_mul (w, u, v);
+ mpi_resize (w, 24);
+ wp = w->d;
+
+#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \
+ sp = ctx->s[(a)]->d; \
+ i = 0; } while (0)
+#define X(a) do { sp[i++] = wp[(a)];} while (0)
+#define X0(a) do { sp[i++] = 0; } while (0)
+ NEXT(0);
+ X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11);
+ NEXT(1);
+ X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();
+ NEXT(2);
+ X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23);
+ NEXT(3);
+ X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);
+ NEXT(4);
+ X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);
+ NEXT(5);
+ X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();
+ NEXT(6);
+ X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();
+ NEXT(7);
+ X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);
+ NEXT(8);
+ X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0();
+ NEXT(9);
+ X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0();
+#undef X0
+#undef X
+#undef NEXT
+ mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
+ mpi_add (ctx->c, ctx->c, ctx->s[1]);
+ mpi_add (ctx->c, ctx->c, ctx->s[2]);
+ mpi_add (ctx->c, ctx->c, ctx->s[3]);
+ mpi_add (ctx->c, ctx->c, ctx->s[4]);
+ mpi_add (ctx->c, ctx->c, ctx->s[5]);
+ mpi_add (ctx->c, ctx->c, ctx->s[6]);
+ mpi_sub (ctx->c, ctx->c, ctx->s[7]);
+ mpi_sub (ctx->c, ctx->c, ctx->s[8]);
+ mpi_sub (ctx->c, ctx->c, ctx->s[9]);
+
+ while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
+ mpi_sub ( ctx->c, ctx->c, ctx->p );
+ while ( ctx->c->sign )
+ mpi_add ( ctx->c, ctx->c, ctx->p );
+ mpi_set (w, ctx->c);
+ }
+ else
+#endif /*0*/
+ mpi_mulm (w, u, v, ctx->p);
+}
+
+static void
+ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
+ mpi_ec_t ctx)
+{
+ mpi_powm (w, b, e, ctx->p);
+}
+
+static void
+ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx)
+{
+ mpi_invm (x, a, ctx->p);
+}
+
+
+
+/* This function returns a new context for elliptic curve based on the
+ field GF(p). P is the prime specifying thuis field, A is the first
+ coefficient.
+
+ This context needs to be released using _gcry_mpi_ec_free. */
+mpi_ec_t
+_gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a)
+{
+ int i;
+ mpi_ec_t ctx;
+ gcry_mpi_t tmp;
+
+ mpi_normalize (p);
+ mpi_normalize (a);
+
+ /* Fixme: Do we want to check some constraints? e.g.
+ a < p
+ */
+
+ ctx = gcry_xcalloc (1, sizeof *ctx);
+
+ ctx->p = mpi_copy (p);
+ ctx->a = mpi_copy (a);
+
+ tmp = mpi_alloc_like (ctx->p);
+ mpi_sub_ui (tmp, ctx->p, 3);
+ ctx->a_is_pminus3 = !mpi_cmp (ctx->a, tmp);
+ mpi_free (tmp);
+
+
+ /* Allocate constants. */
+ ctx->one = mpi_alloc_set_ui (1);
+ ctx->two = mpi_alloc_set_ui (2);
+ ctx->three = mpi_alloc_set_ui (3);
+ ctx->four = mpi_alloc_set_ui (4);
+ ctx->eight = mpi_alloc_set_ui (8);
+ ctx->two_inv_p = mpi_alloc (0);
+ ec_invm (ctx->two_inv_p, ctx->two, ctx);
+
+ /* Allocate scratch variables. */
+ for (i=0; i< DIM(ctx->scratch); i++)
+ ctx->scratch[i] = mpi_alloc_like (ctx->p);
+
+ /* Prepare for fast reduction. */
+ /* FIXME: need a test for NIST values. However it does not gain us
+ any real advantage, for 384 bits it is actually slower than using
+ mpi_mulm. */
+/* ctx->nist_nbits = mpi_get_nbits (ctx->p); */
+/* if (ctx->nist_nbits == 192) */
+/* { */
+/* for (i=0; i < 4; i++) */
+/* ctx->s[i] = mpi_new (192); */
+/* ctx->c = mpi_new (192*2); */
+/* } */
+/* else if (ctx->nist_nbits == 384) */
+/* { */
+/* for (i=0; i < 10; i++) */
+/* ctx->s[i] = mpi_new (384); */
+/* ctx->c = mpi_new (384*2); */
+/* } */
+
+ return ctx;
+}
+
+void
+_gcry_mpi_ec_free (mpi_ec_t ctx)
+{
+ int i;
+
+ if (!ctx)
+ return;
+
+ mpi_free (ctx->p);
+ mpi_free (ctx->a);
+
+ mpi_free (ctx->one);
+ mpi_free (ctx->two);
+ mpi_free (ctx->three);
+ mpi_free (ctx->four);
+ mpi_free (ctx->eight);
+
+ mpi_free (ctx->two_inv_p);
+
+ for (i=0; i< DIM(ctx->scratch); i++)
+ mpi_free (ctx->scratch[i]);
+
+/* if (ctx->nist_nbits == 192) */
+/* { */
+/* for (i=0; i < 4; i++) */
+/* mpi_free (ctx->s[i]); */
+/* mpi_free (ctx->c); */
+/* } */
+/* else if (ctx->nist_nbits == 384) */
+/* { */
+/* for (i=0; i < 10; i++) */
+/* mpi_free (ctx->s[i]); */
+/* mpi_free (ctx->c); */
+/* } */
+
+ gcry_free (ctx);
+}
+
+/* Compute the affine coordinates from the projective coordinates in
+ POINT. Set them into X and Y. If one coordinate is not required,
+ X or Y may be passed as NULL. CTX is the usual context. Returns: 0
+ on success or !0 if POINT is at infinity. */
+int
+_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
+ mpi_ec_t ctx)
+{
+ gcry_mpi_t z1, z2, z3;
+
+ if (!mpi_cmp_ui (point->z, 0))
+ return -1;
+
+ z1 = mpi_new (0);
+ z2 = mpi_new (0);
+ ec_invm (z1, point->z, ctx); /* z1 = z^(-1) mod p */
+ ec_mulm (z2, z1, z1, ctx); /* z2 = z^(-2) mod p */
+
+ if (x)
+ ec_mulm (x, point->x, z2, ctx);
+
+ if (y)
+ {
+ z3 = mpi_new (0);
+ ec_mulm (z3, z2, z1, ctx); /* z3 = z^(-3) mod p */
+ ec_mulm (y, point->y, z3, ctx);
+ mpi_free (z3);
+ }
+
+ mpi_free (z2);
+ mpi_free (z1);
+ return 0;
+}
+
+
+
+
+
+/* RESULT = 2 * POINT */
+void
+_gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
+{
+#define x3 (result->x)
+#define y3 (result->y)
+#define z3 (result->z)
+#define t1 (ctx->scratch[0])
+#define t2 (ctx->scratch[1])
+#define t3 (ctx->scratch[2])
+#define l1 (ctx->scratch[3])
+#define l2 (ctx->scratch[4])
+#define l3 (ctx->scratch[5])
+
+ if (!mpi_cmp_ui (point->y, 0) || !mpi_cmp_ui (point->z, 0))
+ {
+ /* P_y == 0 || P_z == 0 => [1:1:0] */
+ mpi_set_ui (x3, 1);
+ mpi_set_ui (y3, 1);
+ mpi_set_ui (z3, 0);
+ }
+ else
+ {
+ if (ctx->a_is_pminus3) /* Use the faster case. */
+ {
+ /* L1 = 3(X - Z^2)(X + Z^2) */
+ /* T1: used for Z^2. */
+ /* T2: used for the right term. */
+ ec_powm (t1, point->z, ctx->two, ctx);
+ ec_subm (l1, point->x, t1, ctx);
+ ec_mulm (l1, l1, ctx->three, ctx);
+ ec_addm (t2, point->x, t1, ctx);
+ ec_mulm (l1, l1, t2, ctx);
+ }
+ else /* Standard case. */
+ {
+ /* L1 = 3X^2 + aZ^4 */
+ /* T1: used for aZ^4. */
+ ec_powm (l1, point->x, ctx->two, ctx);
+ ec_mulm (l1, l1, ctx->three, ctx);
+ ec_powm (t1, point->z, ctx->four, ctx);
+ ec_mulm (t1, t1, ctx->a, ctx);
+ ec_addm (l1, l1, t1, ctx);
+ }
+ /* Z3 = 2YZ */
+ ec_mulm (z3, point->y, point->z, ctx);
+ ec_mulm (z3, z3, ctx->two, ctx);
+
+ /* L2 = 4XY^2 */
+ /* T2: used for Y2; required later. */
+ ec_powm (t2, point->y, ctx->two, ctx);
+ ec_mulm (l2, t2, point->x, ctx);
+ ec_mulm (l2, l2, ctx->four, ctx);
+
+ /* X3 = L1^2 - 2L2 */
+ /* T1: used for L2^2. */
+ ec_powm (x3, l1, ctx->two, ctx);
+ ec_mulm (t1, l2, ctx->two, ctx);
+ ec_subm (x3, x3, t1, ctx);
+
+ /* L3 = 8Y^4 */
+ /* T2: taken from above. */
+ ec_powm (t2, t2, ctx->two, ctx);
+ ec_mulm (l3, t2, ctx->eight, ctx);
+
+ /* Y3 = L1(L2 - X3) - L3 */
+ ec_subm (y3, l2, x3, ctx);
+ ec_mulm (y3, y3, l1, ctx);
+ ec_subm (y3, y3, l3, ctx);
+ }
+
+#undef x3
+#undef y3
+#undef z3
+#undef t1
+#undef t2
+#undef t3
+#undef l1
+#undef l2
+#undef l3
+}
+
+
+
+/* RESULT = P1 + P2 */
+void
+_gcry_mpi_ec_add_points (mpi_point_t *result,
+ mpi_point_t *p1, mpi_point_t *p2,
+ mpi_ec_t ctx)
+{
+#define x1 (p1->x )
+#define y1 (p1->y )
+#define z1 (p1->z )
+#define x2 (p2->x )
+#define y2 (p2->y )
+#define z2 (p2->z )
+#define x3 (result->x)
+#define y3 (result->y)
+#define z3 (result->z)
+#define l1 (ctx->scratch[0])
+#define l2 (ctx->scratch[1])
+#define l3 (ctx->scratch[2])
+#define l4 (ctx->scratch[3])
+#define l5 (ctx->scratch[4])
+#define l6 (ctx->scratch[5])
+#define l7 (ctx->scratch[6])
+#define l8 (ctx->scratch[7])
+#define l9 (ctx->scratch[8])
+#define t1 (ctx->scratch[9])
+#define t2 (ctx->scratch[10])
+
+ if ( (!mpi_cmp (x1, x2)) && (!mpi_cmp (y1, y2)) && (!mpi_cmp (z1, z2)) )
+ {
+ /* Same point; need to call the duplicate function. */
+ _gcry_mpi_ec_dup_point (result, p1, ctx);
+ }
+ else if (!mpi_cmp_ui (z1, 0))
+ {
+ /* P1 is at infinity. */
+ mpi_set (x3, p2->x);
+ mpi_set (y3, p2->y);
+ mpi_set (z3, p2->z);
+ }
+ else if (!mpi_cmp_ui (z2, 0))
+ {
+ /* P2 is at infinity. */
+ mpi_set (x3, p1->x);
+ mpi_set (y3, p1->y);
+ mpi_set (z3, p1->z);
+ }
+ else
+ {
+ int z1_is_one = !mpi_cmp_ui (z1, 1);
+ int z2_is_one = !mpi_cmp_ui (z2, 1);
+
+ /* l1 = x1 z2^2 */
+ /* l2 = x2 z1^2 */
+ if (z2_is_one)
+ mpi_set (l1, x1);
+ else
+ {
+ ec_powm (l1, z2, ctx->two, ctx);
+ ec_mulm (l1, l1, x1, ctx);
+ }
+ if (z1_is_one)
+ mpi_set (l2, x1);
+ else
+ {
+ ec_powm (l2, z1, ctx->two, ctx);
+ ec_mulm (l2, l2, x2, ctx);
+ }
+ /* l3 = l1 - l2 */
+ ec_subm (l3, l1, l2, ctx);
+ /* l4 = y1 z2^3 */
+ ec_powm (l4, z2, ctx->three, ctx);
+ ec_mulm (l4, l4, y1, ctx);
+ /* l5 = y2 z1^3 */
+ ec_powm (l5, z1, ctx->three, ctx);
+ ec_mulm (l5, l5, y2, ctx);
+ /* l6 = l4 - l5 */
+ ec_subm (l6, l4, l5, ctx);
+
+ if (!mpi_cmp_ui (l3, 0))
+ {
+ if (!mpi_cmp_ui (l6, 0))
+ {
+ /* P1 and P2 are the same - use duplicate function. */
+ _gcry_mpi_ec_dup_point (result, p1, ctx);
+ }
+ else
+ {
+ /* P1 is the inverse of P2. */
+ mpi_set_ui (x3, 1);
+ mpi_set_ui (y3, 1);
+ mpi_set_ui (z3, 0);
+ }
+ }
+ else
+ {
+ /* l7 = l1 + l2 */
+ ec_addm (l7, l1, l2, ctx);
+ /* l8 = l4 + l5 */
+ ec_addm (l8, l4, l5, ctx);
+ /* z3 = z1 z2 l3 */
+ ec_mulm (z3, z1, z2, ctx);
+ ec_mulm (z3, z3, l3, ctx);
+ /* x3 = l6^2 - l7 l3^2 */
+ ec_powm (t1, l6, ctx->two, ctx);
+ ec_powm (t2, l3, ctx->two, ctx);
+ ec_mulm (t2, t2, l7, ctx);
+ ec_subm (x3, t1, t2, ctx);
+ /* l9 = l7 l3^2 - 2 x3 */
+ ec_mulm (t1, x3, ctx->two, ctx);
+ ec_subm (l9, t2, t1, ctx);
+ /* y3 = (l9 l6 - l8 l3^3)/2 */
+ ec_mulm (l9, l9, l6, ctx);
+ ec_powm (t1, l3, ctx->three, ctx); /* fixme: Use saved value*/
+ ec_mulm (t1, t1, l8, ctx);
+ ec_subm (y3, l9, t1, ctx);
+ ec_mulm (y3, y3, ctx->two_inv_p, ctx);
+ }
+ }
+
+#undef x1
+#undef y1
+#undef z1
+#undef x2
+#undef y2
+#undef z2
+#undef x3
+#undef y3
+#undef z3
+#undef l1
+#undef l2
+#undef l3
+#undef l4
+#undef l5
+#undef l6
+#undef l7
+#undef l8
+#undef l9
+#undef t1
+#undef t2
+}
+
+
+
+/* Scalar point multiplication - the main function for ECC. If takes
+ an integer SCALAR and a POINT as well as the usual context CTX.
+ RESULT will be set to the resulting point. */
+void
+_gcry_mpi_ec_mul_point (mpi_point_t *result,
+ gcry_mpi_t scalar, mpi_point_t *point,
+ mpi_ec_t ctx)
+{
+#if 0
+ /* Simple left to right binary method. GECC Algorithm 3.27 */
+ unsigned int nbits;
+ int i;
+
+ nbits = mpi_get_nbits (scalar);
+ mpi_set_ui (result->x, 1);
+ mpi_set_ui (result->y, 1);
+ mpi_set_ui (result->z, 0);
+
+ for (i=nbits-1; i >= 0; i--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ if (mpi_test_bit (scalar, i) == 1)
+ _gcry_mpi_ec_add_points (result, result, point, ctx);
+ }
+
+#else
+ gcry_mpi_t x1, y1, z1, k, h, yy;
+ unsigned int i, loops;
+ mpi_point_t p1, p2, p1inv;
+
+ x1 = mpi_alloc_like (ctx->p);
+ y1 = mpi_alloc_like (ctx->p);
+ h = mpi_alloc_like (ctx->p);
+ k = mpi_copy (scalar);
+ yy = mpi_copy (point->y);
+
+ if ( mpi_is_neg (k) )
+ {
+ k->sign = 0;
+ ec_invm (yy, yy, ctx);
+ }
+
+ if (!mpi_cmp_ui (point->z, 1))
+ {
+ mpi_set (x1, point->x);
+ mpi_set (y1, yy);
+ }
+ else
+ {
+ gcry_mpi_t z2, z3;
+
+ z2 = mpi_alloc_like (ctx->p);
+ z3 = mpi_alloc_like (ctx->p);
+ ec_mulm (z2, point->z, point->z, ctx);
+ ec_mulm (z3, point->z, z2, ctx);
+ ec_invm (z2, z2, ctx);
+ ec_mulm (x1, point->x, z2, ctx);
+ ec_invm (z3, z3, ctx);
+ ec_mulm (y1, yy, z3, ctx);
+ mpi_free (z2);
+ mpi_free (z3);
+ }
+ z1 = mpi_copy (ctx->one);
+
+ mpi_mul (h, k, ctx->three); /* h = 3k */
+ loops = mpi_get_nbits (h);
+
+ mpi_set (result->x, point->x);
+ mpi_set (result->y, yy); mpi_free (yy); yy = NULL;
+ mpi_set (result->z, point->z);
+
+ p1.x = x1; x1 = NULL;
+ p1.y = y1; y1 = NULL;
+ p1.z = z1; z1 = NULL;
+ point_init (&p2);
+ point_init (&p1inv);
+
+ for (i=loops-2; i > 0; i--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0)
+ {
+ point_set (&p2, result);
+ _gcry_mpi_ec_add_points (result, &p2, &p1, ctx);
+ }
+ if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
+ {
+ point_set (&p2, result);
+ /* Invert point: y = p - y mod p */
+ point_set (&p1inv, &p1);
+ ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
+ _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
+ }
+ }
+
+ point_free (&p1);
+ point_free (&p2);
+ point_free (&p1inv);
+ mpi_free (h);
+ mpi_free (k);
+#endif
+}
diff --git a/grub-core/lib/libgcrypt/mpi/generic/Manifest b/grub-core/lib/libgcrypt/mpi/generic/Manifest
new file mode 100644
index 0000000..c429fde
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/Manifest
@@ -0,0 +1,29 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.c iQCVAwUAP+Lj2DEAnp832S/7AQKn/AQAwQLWggl6zNQ5EZ+lE+jKV8W3FsogW3/6tp9T5rrSR5JnlWyoHQ9/Pu4knOcLjS6nIfVOiAEifu3nuIysQr9jDSSSJA2LylSUBSXKLKDamPsOCwXOLxiZODslJT3CCGAUtLvXJrWDbTZQrkEuwnLnjQFDzuA7iY9JLrG9kAoXD6Q==WoWm
+mpih-mul1.c iQCVAwUAP+LkCTEAnp832S/7AQKFVQP+MhBNjcY73JtnsHZfnaVZq3TiKwN151cWV51nDc1RnTaMhSIFeuNlj3vNML2W0Gn8n+GnyiWE2XXdQEaik6BL02eekUn9aq7I/rdpnTHuOjQPK1uwjuNl8RuJ9YrERBAxq4oB71f+iwMab8dsMSUlVC+NdeAocRqLLgnR/efkdLc==2Tkb
+mpih-mul2.c iQCVAwUAP+LkMjEAnp832S/7AQLPeAQAqmRzxFe/mDqTdZr/pTXT8RVyB1vKB0Ei2THV05BxmI4OPv39uysfFpLMt/INsX7AGqdOlj4jOZ/qNaFXR1ceMrlSXvo8u/epk6rCXFp82kM7Qs983LjoP//PrMCkYkXwblaVrgUGiBUCbuPMliWTK6qKkxxXtEfqZ7nVbEWdBx8==Kwhl
+mpih-mul3.c iQCVAwUAP+LkVDEAnp832S/7AQL91gP/Qd5iZWxRiN5DdEIVHAedoNvl23NPrT2UUdXvnSK49DpplTxkLiMBj0WqCayG/YIET2NpMRCeLvAZNcSt6lOm0bSZDYo1Hv/N+UoqD3V1McjY16REBv/nnPaMWMZcx7rl5yKTVZiX2PgV6oQOL7Yfrt5ZIOlrHBRs9S2/zcCaVz0==9BQe
+mpih-lshift.c iQCVAwUAP+LlATEAnp832S/7AQIACAQAhMrpx0SRXE/LN1NkjMO9n74nMrvmzYJyru0gw2O4BYrUPvD/LWGju2FZaggKV0IBjmi0cDoCrNeK9EGjKOO1lfgODbX2IZ1LUhr9jDuMj0QRqj6T9YkAFYTNUk4GfpwIf7T6Ybo7c78Jx93PidCJt7d39eMMEalooC7LZ4IU3NM==nZ4k
+mpih-rshift.c iQCVAwUAP+LlIjEAnp832S/7AQKiuAP/eYC2ZScd+taBx/kNzRvGjA0eAXvORMkMLV6Ot+OXVzVUi04eoP2yXdxSNFKwUj12p8GWXkdoMG3aOGBKg2a7bY5Q5RUho3hUWb9UsVYVUfXLf7IOTt/3a6MLh2CmV5dFPWJmSlbCyQRcn6n/fLDeJ3A2bWTS/BhqGfpOXUIU1ws==jCf8
+mpih-sub1.c iQCVAwUAP+LlZzEAnp832S/7AQIEPgP/dLHTDRbPrYJhsLp9SjGstU1M8/IC5XytcDtO3NQeu4mx6vaXjpujtsTvKIbX4QL5IahNntVVKv1xFLEm2yFg7L2ns0uD/mfwGgOhCG1j2o/SaTAWP5KxP7ae5UDcZl2w6NWvEuMj9t32zmziAZjP8W73A37FUspeRDYiL9sQzkI==QQzk
+udiv-w-sdiv.c iQCVAwUAP+Lk0TEAnp832S/7AQICXAQAsxe1SQD4+xZaZTqBC0V9Cyuo0mrdccnRFzthOtm0ARwKFXU2cuLW/ZBOkmeWOVmOFhBp22/I8dEGYnMA3gcfmOMCpNu9i9zk/XHfptdunA1MnOe3GsoWgfHL0rhpAyPhp/X043ICB41NElnnuxADuQQlD4Z1fca5ygYxMr2crJg==EI/6
+mpi-asm-defs.h iQCVAwUAP+LkgDEAnp832S/7AQK0FgQAxJZ7xvXhoZa33GWe23LRb3asrno/loZSyAIXrntqtVH8M3pEsCY0OyW4ry4hX2RnxpuhRCM/PdRNLG3xXyMSVIhkHU8WVRLqzF2LLjEkyU3cAmHnnTQ9aO/XpUWtJGTZ8q2bv7ZsAEi4aPl0p6KhPXcPgM9vQ2XcyOPn3Dl0d6Q==xpjI
+$names$ iQCVAwUAP+LmNDEAnp832S/7AQJa+gP+KQNJpbNOgc+s2UX+Ya2gDaOFcAROImIllhg3ej8EaBF8xxdHmWT1zaKwTwi3moEEleykMR104YAGWyQeMbFYiuPPBW+ohrT6KxRBVJpIA9auOOqqJMyglZyoR3Hv7gduVYUW1h/DebnqiKXKEfzQDFqYuT0ayuteoOR4B5NICbE==nLSh
diff --git a/grub-core/lib/libgcrypt/mpi/generic/distfiles b/grub-core/lib/libgcrypt/mpi/generic/distfiles
new file mode 100644
index 0000000..9810eef
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/distfiles
@@ -0,0 +1,11 @@
+Manifest
+mpih-add1.c
+mpih-mul1.c
+mpih-mul2.c
+mpih-mul3.c
+mpih-lshift.c
+mpih-rshift.c
+mpih-sub1.c
+udiv-w-sdiv.c
+mpi-asm-defs.h
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h b/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h
new file mode 100644
index 0000000..13424e2
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h
@@ -0,0 +1,10 @@
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
+
+
+
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c
new file mode 100644
index 0000000..4a84df6
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c
@@ -0,0 +1,65 @@
+/* mpihelp-add_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998,
+ * 2000, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to one addend */
+ cy = y < cy; /* get out carry from that addition */
+ y += x; /* add other addend */
+ cy += y < x; /* get out carry from that add, combine */
+ res_ptr[j] = y;
+ }
+ while ( ++j );
+
+ return cy;
+}
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c
new file mode 100644
index 0000000..f48c12c
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c
@@ -0,0 +1,68 @@
+/* mpi-lshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
+ * and store the USIZE least significant digits of the result at WP.
+ * Return the bits shifted out from the most significant digit.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be >= UP.
+ */
+
+mpi_limb_t
+_gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned int cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp += 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ i = usize - 1;
+ low_limb = up[i];
+ retval = low_limb >> sh_2;
+ high_limb = low_limb;
+ while ( --i >= 0 )
+ {
+ low_limb = up[i];
+ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+ high_limb = low_limb;
+ }
+ wp[i] = high_limb << sh_1;
+
+ return retval;
+}
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c
new file mode 100644
index 0000000..0e8197d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c
@@ -0,0 +1,62 @@
+/* mpihelp-mul_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+
+ /* The loop counter and index J goes from -S1_SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ res_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+ res_ptr[j] = prod_low;
+ }
+ while( ++j );
+
+ return cy_limb;
+}
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c
new file mode 100644
index 0000000..3b75496
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c
@@ -0,0 +1,68 @@
+/* mpih-mul2.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+mpi_limb_t
+_gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+ mpi_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x + prod_low;
+ cy_limb += prod_low < x?1:0;
+ res_ptr[j] = prod_low;
+ }
+ while ( ++j );
+
+ return cy_limb;
+}
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c
new file mode 100644
index 0000000..5e84f94
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c
@@ -0,0 +1,68 @@
+/* mpih-mul3.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+mpi_limb_t
+_gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+ mpi_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x - prod_low;
+ cy_limb += prod_low > x?1:0;
+ res_ptr[j] = prod_low;
+ }
+ while( ++j );
+
+ return cy_limb;
+}
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c
new file mode 100644
index 0000000..e40794f
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c
@@ -0,0 +1,67 @@
+/* mpih-rshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2000, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+
+/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
+ * and store the USIZE least significant limbs of the result at WP.
+ * The bits shifted out to the right are returned.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be <= UP.
+ */
+
+mpi_limb_t
+_gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp -= 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ high_limb = up[0];
+ retval = high_limb << sh_2;
+ low_limb = high_limb;
+ for (i=1; i < usize; i++)
+ {
+ high_limb = up[i];
+ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
+ low_limb = high_limb;
+ }
+ wp[i] = low_limb >> sh_1;
+
+ return retval;
+}
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c
new file mode 100644
index 0000000..e88821b
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c
@@ -0,0 +1,66 @@
+/* mpihelp-add_2.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to subtrahend */
+ cy = y < cy; /* get out carry from that addition */
+ y = x - y; /* main subtract */
+ cy += y > x; /* get out carry from the subtract, combine */
+ res_ptr[j] = y;
+ }
+ while( ++j );
+
+ return cy;
+}
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c b/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c
new file mode 100644
index 0000000..e80d98b
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c
@@ -0,0 +1,133 @@
+/* mpih-w-sdiv -- implement udiv_qrnnd on machines with only signed
+ * division.
+ * Copyright (C) 1992, 1994, 1996, 1998, 2002 Free Software Foundation, Inc.
+ * Contributed by Peter L. Montgomery.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+#if 0 /* not yet ported to MPI */
+
+mpi_limb_t
+mpihelp_udiv_w_sdiv( mpi_limp_t *rp,
+ mpi_limp_t *a1,
+ mpi_limp_t *a0,
+ mpi_limp_t *d )
+{
+ mp_limb_t q, r;
+ mp_limb_t c0, c1, b1;
+
+ if ((mpi_limb_signed_t) d >= 0)
+ {
+ if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1)))
+ {
+ /* dividend, divisor, and quotient are nonnegative */
+ sdiv_qrnnd (q, r, a1, a0, d);
+ }
+ else
+ {
+ /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
+ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1));
+ /* Divide (c1*2^32 + c0) by d */
+ sdiv_qrnnd (q, r, c1, c0, d);
+ /* Add 2^31 to quotient */
+ q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
+ }
+ }
+ else
+ {
+ b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
+ c1 = a1 >> 1; /* A/2 */
+ c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1);
+
+ if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
+ {
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
+ {
+ c1 = (b1 - 1) - c1;
+ c0 = ~c0; /* logical NOT */
+
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ q = ~q; /* (A/2)/b1 */
+ r = (b1 - 1) - r;
+
+ r = 2*r + (a0 & 1); /* A/(2*b1) */
+
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else /* Implies c1 = b1 */
+ { /* Hence a1 = d - 1 = 2*b1 - 1 */
+ if (a0 >= -d)
+ {
+ q = -1;
+ r = a0 + d;
+ }
+ else
+ {
+ q = -2;
+ r = a0 + 2*d;
+ }
+ }
+ }
+
+ *rp = r;
+ return q;
+}
+
+#endif
+
diff --git a/grub-core/lib/libgcrypt/mpi/hppa/README b/grub-core/lib/libgcrypt/mpi/hppa/README
new file mode 100644
index 0000000..5a2d5fd
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/hppa/README
@@ -0,0 +1,84 @@
+This directory contains mpn functions for various HP PA-RISC chips. Code
+that runs faster on the PA7100 and later implementations, is in the pa7100
+directory.
+
+RELEVANT OPTIMIZATION ISSUES
+
+ Load and Store timing
+
+On the PA7000 no memory instructions can issue the two cycles after a store.
+For the PA7100, this is reduced to one cycle.
+
+The PA7100 has a lookup-free cache, so it helps to schedule loads and the
+dependent instruction really far from each other.
+
+STATUS
+
+1. mpn_mul_1 could be improved to 6.5 cycles/limb on the PA7100, using the
+ instructions bwlow (but some sw pipelining is needed to avoid the
+ xmpyu-fstds delay):
+
+ fldds s1_ptr
+
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+
+ addib Loop
+
+2. mpn_addmul_1 could be improved from the current 10 to 7.5 cycles/limb
+ (asymptotically) on the PA7100, using the instructions below. With proper
+ sw pipelining and the unrolling level below, the speed becomes 8
+ cycles/limb.
+
+ fldds s1_ptr
+ fldds s1_ptr
+
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ addc
+ addc
+ addc
+ addc
+ addc %r0,%r0,cy-limb
+
+ ldws res_ptr
+ ldws res_ptr
+ ldws res_ptr
+ ldws res_ptr
+ add
+ stws res_ptr
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+
+ addib
diff --git a/grub-core/lib/libgcrypt/mpi/hppa/distfiles b/grub-core/lib/libgcrypt/mpi/hppa/distfiles
new file mode 100644
index 0000000..7f24205
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/hppa/distfiles
@@ -0,0 +1,7 @@
+README
+udiv-qrnnd.S
+mpih-add1.S
+mpih-sub1.S
+mpih-lshift.S
+mpih-rshift.S
+
diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S
new file mode 100644
index 0000000..3bc0e5e
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S
@@ -0,0 +1,70 @@
+/* hppa add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Fee Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (gr26)
+ * mpi_ptr_t s1_ptr, (gr25)
+ * mpi_ptr_t s2_ptr, (gr24)
+ * mpi_size_t size) (gr23)
+ *
+ * One might want to unroll this as for other processors, but it turns
+ * out that the data cache contention after a store makes such
+ * unrolling useless. We can't come under 5 cycles/limb anyway.
+ */
+
+ .code
+ .export _gcry_mpih_add_n
+ .label _gcry_mpih_add_n
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,= -1,%r23,L$end ; check for (SIZE == 1)
+ add %r20,%r19,%r28 ; add first limbs ignoring cy
+
+ .label L$loop
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,<> -1,%r23,L$loop
+ addc %r20,%r19,%r28
+
+ .label L$end
+ stws %r28,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r0,%r28
+
+ .exit
+ .procend
diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S
new file mode 100644
index 0000000..91b29bb
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S
@@ -0,0 +1,77 @@
+/* hppa lshift
+ *
+ * Copyright (C) 1992, 1994, 1998
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_lshift
+ .label _gcry_mpih_lshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(0,%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L$0004
+ vshd %r0,%r22,%r28 ; compute carry out limb
+ ldws,mb -4(0,%r25),%r29
+ addib,= -1,%r24,L$0002
+ vshd %r22,%r29,%r20
+
+ .label L$loop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ addib,= -1,%r24,L$0003
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,<> -1,%r24,L$loop
+ vshd %r22,%r29,%r20
+
+ .label L$0002
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+ .label L$0003
+ stws,mb %r20,-4(0,%r26)
+ .label L$0004
+ vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+
+ .exit
+ .procend
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S
new file mode 100644
index 0000000..37a9d4e
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S
@@ -0,0 +1,73 @@
+/* hppa rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_rshift
+ .label _gcry_mpih_rshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L$r004
+ vshd %r22,%r0,%r28 ; compute carry out limb
+ ldws,ma 4(0,%r25),%r29
+ addib,= -1,%r24,L$r002
+ vshd %r29,%r22,%r20
+
+ .label L$roop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ addib,= -1,%r24,L$r003
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,<> -1,%r24,L$roop
+ vshd %r29,%r22,%r20
+
+ .label L$r002
+ stws,ma %r20,4(0,%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+ .label L$r003
+ stws,ma %r20,4(0,%r26)
+ .label L$r004
+ vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+
+ .exit
+ .procend
+
diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S
new file mode 100644
index 0000000..8d197e4
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S
@@ -0,0 +1,78 @@
+/* hppa sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (gr26)
+ * mpi_ptr_t s1_ptr, (gr25)
+ * mpi_ptr_t s2_ptr, (gr24)
+ * mpi_size_t size) (gr23)
+ *
+ * One might want to unroll this as for other processors, but it turns
+ * out that the data cache contention after a store makes such
+ * unrolling useless. We can't come under 5 cycles/limb anyway.
+ */
+
+
+ .code
+ .export _gcry_mpih_sub_n
+ .label _gcry_mpih_sub_n
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,= -1,%r23,L$end ; check for (SIZE == 1)
+ sub %r20,%r19,%r28 ; subtract first limbs ignoring cy
+
+ .label L$loop
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,<> -1,%r23,L$loop
+ subb %r20,%r19,%r28
+
+ .label L$end
+ stws %r28,0(0,%r26)
+ addc %r0,%r0,%r28
+ bv 0(%r2)
+ subi 1,%r28,%r28
+
+ .exit
+ .procend
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S b/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S
new file mode 100644
index 0000000..59ebf7a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S
@@ -0,0 +1,297 @@
+/* HP-PA __udiv_qrnnd division support, used from longlong.h.
+ * This version runs fast on pre-PA7000 CPUs.
+ *
+ * Copyright (C) 1993, 1994, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/* INPUT PARAMETERS
+ * rem_ptr gr26
+ * n1 gr25
+ * n0 gr24
+ * d gr23
+ *
+ * The code size is a bit excessive. We could merge the last two ds;addc
+ * sequences by simply moving the "bb,< Odd" instruction down. The only
+ * trouble is the FFFFFFFF code that would need some hacking.
+ */
+
+ .code
+ .export __udiv_qrnnd
+ .label __udiv_qrnnd
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ comb,< %r23,0,L$largedivisor
+ sub %r0,%r23,%r1 ; clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r28
+ ds %r25,%r23,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r23,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r28,%r28,%r28
+
+ .label L$largedivisor
+ extru %r24,31,1,%r19 ; r19 = n0 & 1
+ bb,< %r23,31,L$odd
+ extru %r23,30,31,%r22 ; r22 = d >> 1
+ shd %r25,%r24,1,%r24 ; r24 = new n0
+ extru %r25,30,31,%r25 ; r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r19,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r24,%r24,%r28
+
+ .label L$odd
+ addib,sv,n 1,%r22,L$FF.. ; r22 = (d / 2 + 1)
+ shd %r25,%r24,1,%r24 ; r24 = new n0
+ extru %r25,30,31,%r25 ; r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r28
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r19,%r25
+; We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25
+ add,nuv %r28,%r25,%r25
+ addl %r25,%r1,%r25
+ addc %r0,%r28,%r28
+ sub,<< %r25,%r23,%r0
+ addl %r25,%r1,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r28,%r28
+
+; This is just a special case of the code above.
+; We come here when d == 0xFFFFFFFF
+ .label L$FF..
+ add,uv %r25,%r24,%r24
+ sub,<< %r24,%r23,%r0
+ ldo 1(%r24),%r24
+ stws %r24,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r25,%r28
+
+ .exit
+ .procend
diff --git a/grub-core/lib/libgcrypt/mpi/i386/Manifest b/grub-core/lib/libgcrypt/mpi/i386/Manifest
new file mode 100644
index 0000000..812bc8a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/Manifest
@@ -0,0 +1,28 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+syntax.h
+$names$ iQCVAwUAP+LmOTEAnp832S/7AQJZmgQA1+GIl7rXiEY00y5xD2kG5Lm2QD6c9aBME8hTl812OEcj0ul/QSpdv8E2NEKooifr4SiLVhEVfLNaLqAgN3cIsttn3rRX3/pMC5JwSKHDJPsUbpN9tzb5dr2YC9GG9m8xngAQrN11IQPnGfvFLJK+oDnEMIAeHDpOnX9NeQPDAQA==bnOy
diff --git a/grub-core/lib/libgcrypt/mpi/i386/distfiles b/grub-core/lib/libgcrypt/mpi/i386/distfiles
new file mode 100644
index 0000000..22b9979
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/distfiles
@@ -0,0 +1,10 @@
+Manifest
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+syntax.h
+
diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S
new file mode 100644
index 0000000..652b232
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S
@@ -0,0 +1,116 @@
+/* i80386 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ pushl %edi
+ pushl %esi
+
+ movl 12(%esp),%edi /* res_ptr */
+ movl 16(%esp),%esi /* s1_ptr */
+ movl 20(%esp),%edx /* s2_ptr */
+ movl 24(%esp),%ecx /* size */
+
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz Loop /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L0
+L0: leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(Loop-L0-3),%eax
+ addl $4,%esp
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (Loop - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+Loop: movl (%esi),%eax
+ adcl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ adcl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ adcl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ adcl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ adcl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ adcl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ adcl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ adcl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz Loop
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S
new file mode 100644
index 0000000..bf8ed9d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S
@@ -0,0 +1,94 @@
+/* i80386 lshift
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+
+ movl 16(%esp),%edi /* res_ptr */
+ movl 20(%esp),%esi /* s_ptr */
+ movl 24(%esp),%edx /* size */
+ movl 28(%esp),%ecx /* cnt */
+
+ subl $4,%esi /* adjust s_ptr */
+
+ movl (%esi,%edx,4),%ebx /* read most significant limb */
+ xorl %eax,%eax
+ shldl %cl,%ebx,%eax /* compute carry limb */
+ decl %edx
+ jz Lend
+ pushl %eax /* push carry limb onto stack */
+ testb $1,%dl
+ jnz L1 /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+Loop: movl (%esi,%edx,4),%ebx /* load next lower limb */
+ shldl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ decl %edx
+L1: movl (%esi,%edx,4),%eax
+ shldl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ decl %edx
+ jnz Loop
+
+ shll %cl,%eax /* compute least significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+Lend: shll %cl,%ebx /* compute least significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S
new file mode 100644
index 0000000..c9760ef
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S
@@ -0,0 +1,84 @@
+/* i80386 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S
new file mode 100644
index 0000000..9794e11
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S
@@ -0,0 +1,86 @@
+/* i80386 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(add,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S
new file mode 100644
index 0000000..6df2017
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S
@@ -0,0 +1,86 @@
+/* i80386 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(sub,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S
new file mode 100644
index 0000000..2920e55
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S
@@ -0,0 +1,97 @@
+/* i80386 rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+
+ movl 16(%esp),%edi /* wp */
+ movl 20(%esp),%esi /* up */
+ movl 24(%esp),%edx /* usize */
+ movl 28(%esp),%ecx /* cnt */
+
+ leal -4(%edi,%edx,4),%edi
+ leal (%esi,%edx,4),%esi
+ negl %edx
+
+ movl (%esi,%edx,4),%ebx /* read least significant limb */
+ xorl %eax,%eax
+ shrdl %cl,%ebx,%eax /* compute carry limb */
+ incl %edx
+ jz Lend2
+ pushl %eax /* push carry limb onto stack */
+ testb $1,%dl
+ jnz L2 /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+Loop2: movl (%esi,%edx,4),%ebx /* load next higher limb */
+ shrdl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ incl %edx
+L2: movl (%esi,%edx,4),%eax
+ shrdl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ incl %edx
+ jnz Loop2
+
+ shrl %cl,%eax /* compute most significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+Lend2: shrl %cl,%ebx /* compute most significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S
new file mode 100644
index 0000000..f447f7a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S
@@ -0,0 +1,117 @@
+/* i80386 sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+ pushl %edi
+ pushl %esi
+
+ movl 12(%esp),%edi /* res_ptr */
+ movl 16(%esp),%esi /* s1_ptr */
+ movl 20(%esp),%edx /* s2_ptr */
+ movl 24(%esp),%ecx /* size */
+
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz Loop /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L0
+L0: leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(Loop-L0-3),%eax
+ addl $4,%esp
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (Loop - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+Loop: movl (%esi),%eax
+ sbbl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ sbbl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ sbbl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ sbbl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ sbbl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ sbbl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ sbbl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ sbbl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz Loop
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i386/syntax.h b/grub-core/lib/libgcrypt/mpi/i386/syntax.h
new file mode 100644
index 0000000..39ede98
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i386/syntax.h
@@ -0,0 +1,68 @@
+/* syntax.h -- Definitions for x86 syntax variations.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#undef ALIGN
+
+#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX)
+#define R(r) %r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)displacement(R(base))
+#define MEM_INDEX(base,index,size)(R(base),R(index),size)
+#ifdef __STDC__
+#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst
+#else
+#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst
+#endif
+#define TEXT .text
+#if defined (BSD_SYNTAX)
+#define ALIGN(log) .align log
+#endif
+#if defined (ELF_SYNTAX)
+#define ALIGN(log) .align 1<<(log)
+#endif
+#define GLOBL .globl
+#endif
+
+#ifdef INTEL_SYNTAX
+#define R(r) r
+#define MEM(base)[base]
+#define MEM_DISP(base,displacement)[base+(displacement)]
+#define MEM_INDEX(base,index,size)[base+index*size]
+#define INSN1(mnemonic,size_suffix,dst)mnemonic dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src
+#define TEXT .text
+#define ALIGN(log) .align log
+#define GLOBL .globl
+#endif
+
+#ifdef X86_BROKEN_ALIGN
+#undef ALIGN
+#define ALIGN(log) .align log,0x90
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/i586/Manifest b/grub-core/lib/libgcrypt/mpi/i586/Manifest
new file mode 100644
index 0000000..6d1d7f8
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/Manifest
@@ -0,0 +1,27 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+$names$ iQCVAwUAP+LmQDEAnp832S/7AQKCmgQAhG+E7X0KB4qdVf3sMb6Qr+Iv5Jlehzoub/5vxTRgePKzRuOHidCnTzSSoyzA++UcHrOjHQQDMsXnO6PqpS1d/TKkxjnGN7rE8mvMYlFAT8RsawTozSfh14mCzI0HTDbaKL9Z8pcMJtadB3XqAuqWJNO8kyECJFwurt3DRWXSWS8==Rug5
diff --git a/grub-core/lib/libgcrypt/mpi/i586/README b/grub-core/lib/libgcrypt/mpi/i586/README
new file mode 100644
index 0000000..d73b082
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/README
@@ -0,0 +1,26 @@
+This directory contains mpn functions optimized for Intel Pentium
+processors.
+
+RELEVANT OPTIMIZATION ISSUES
+
+1. Pentium doesn't allocate cache lines on writes, unlike most other modern
+processors. Since the functions in the mpn class do array writes, we have to
+handle allocating the destination cache lines by reading a word from it in the
+loops, to achieve the best performance.
+
+2. Pairing of memory operations requires that the two issued operations refer
+to different cache banks. The simplest way to insure this is to read/write
+two words from the same object. If we make operations on different objects,
+they might or might not be to the same cache bank.
+
+STATUS
+
+1. mpn_lshift and mpn_rshift run at about 6 cycles/limb, but the Pentium
+documentation indicates that they should take only 43/8 = 5.375 cycles/limb,
+or 5 cycles/limb asymptotically.
+
+2. mpn_add_n and mpn_sub_n run at asymptotically 2 cycles/limb. Due to loop
+overhead and other delays (cache refill?), they run at or near 2.5 cycles/limb.
+
+3. mpn_mul_1, mpn_addmul_1, mpn_submul_1 all run 1 cycle faster than they
+should...
diff --git a/grub-core/lib/libgcrypt/mpi/i586/distfiles b/grub-core/lib/libgcrypt/mpi/i586/distfiles
new file mode 100644
index 0000000..546f777
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/distfiles
@@ -0,0 +1,10 @@
+Manifest
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+README
+
diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S
new file mode 100644
index 0000000..7436d59
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S
@@ -0,0 +1,135 @@
+/* i80586 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s1_ptr */
+ movl 28(%esp),%ebp /* s2_ptr */
+ movl 32(%esp),%ecx /* size */
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz Lend
+ pushl %edx
+
+ ALIGN (3)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L1: movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %ebx,%eax
+ movl 4(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L2: movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ adcl %ebx,%eax
+ movl 12(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L3: movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ adcl %ebx,%eax
+ movl 20(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L4: movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %ebx,%eax
+ movl 28(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz Loop
+
+ popl %edx
+Lend:
+ decl %edx /* test %edx w/o clobbering carry */
+ js Lend2
+ incl %edx
+Loop2:
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ adcl %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz Loop2
+Lend2:
+ movl (%esi),%eax
+ adcl %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S
new file mode 100644
index 0000000..9d25fe9
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S
@@ -0,0 +1,229 @@
+/* i80586 lshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s_ptr */
+ movl 28(%esp),%ebp /* size */
+ movl 32(%esp),%ecx /* cnt */
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne Lnormal
+ leal 4(%esi),%eax
+ cmpl %edi,%eax
+ jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */
+ leal (%esi,%ebp,4),%eax
+ cmpl %eax,%edi
+ jnc Lspecial /* jump if res_ptr >= s_ptr + size */
+
+Lnormal:
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+ xorl %eax,%eax
+ shldl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz Lend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+Loop: movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ shldl %cl,%eax,%ebx
+ shldl %cl,%edx,%eax
+ movl %ebx,(%edi)
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ shldl %cl,%ebx,%edx
+ shldl %cl,%eax,%ebx
+ movl %edx,-8(%edi)
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ shldl %cl,%edx,%eax
+ shldl %cl,%ebx,%edx
+ movl %eax,-16(%edi)
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ shldl %cl,%eax,%ebx
+ shldl %cl,%edx,%eax
+ movl %ebx,-24(%edi)
+ movl %eax,-28(%edi)
+
+ subl $32,%esi
+ subl $32,%edi
+ decl %ebp
+ jnz Loop
+
+Lend: popl %ebp
+ andl $7,%ebp
+ jz Lend2
+Loop2: movl (%esi),%eax
+ shldl %cl,%eax,%edx
+ movl %edx,(%edi)
+ movl %eax,%edx
+ subl $4,%esi
+ subl $4,%edi
+ decl %ebp
+ jnz Loop2
+
+Lend2: shll %cl,%edx /* compute least significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+Lspecial:
+ movl (%esi),%edx
+ addl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ addl %edx,%edx
+ incl %ebp
+ decl %ebp
+ jz LLend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+LLoop: movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,(%edi)
+ adcl %edx,%edx
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ adcl %ebx,%ebx
+ movl %edx,8(%edi)
+ adcl %eax,%eax
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ adcl %edx,%edx
+ movl %eax,16(%edi)
+ adcl %ebx,%ebx
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,24(%edi)
+ adcl %edx,%edx
+ movl %eax,28(%edi)
+
+ leal 32(%esi),%esi /* use leal not to clobber carry */
+ leal 32(%edi),%edi
+ decl %ebp
+ jnz LLoop
+
+LLend: popl %ebp
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebp
+ jz LLend2
+ addl %eax,%eax /* restore carry from eax */
+LLoop2: movl %edx,%ebx
+ movl (%esi),%edx
+ adcl %edx,%edx
+ movl %ebx,(%edi)
+
+ leal 4(%esi),%esi /* use leal not to clobber carry */
+ leal 4(%edi),%edi
+ decl %ebp
+ jnz LLoop2
+
+ jmp LL1
+LLend2: addl %eax,%eax /* restore carry from eax */
+LL1: movl %edx,(%edi) /* store last limb */
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S
new file mode 100644
index 0000000..3601d96
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S
@@ -0,0 +1,89 @@
+/* i80586 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S
new file mode 100644
index 0000000..f32d363
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S
@@ -0,0 +1,93 @@
+/* i80586 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
+
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(add,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S
new file mode 100644
index 0000000..fa27d4e
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S
@@ -0,0 +1,93 @@
+/* i80586 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
+
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(sub,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S
new file mode 100644
index 0000000..c661e3d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S
@@ -0,0 +1,228 @@
+/* i80586 rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s_ptr */
+ movl 28(%esp),%ebp /* size */
+ movl 32(%esp),%ecx /* cnt */
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne Rnormal
+ leal 4(%edi),%eax
+ cmpl %esi,%eax
+ jnc Rspecial /* jump if res_ptr + 1 >= s_ptr */
+ leal (%edi,%ebp,4),%eax
+ cmpl %eax,%esi
+ jnc Rspecial /* jump if s_ptr >= res_ptr + size */
+
+Rnormal:
+ movl (%esi),%edx
+ addl $4,%esi
+ xorl %eax,%eax
+ shrdl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz Rend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+Roop: movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ shrdl %cl,%eax,%ebx
+ shrdl %cl,%edx,%eax
+ movl %ebx,(%edi)
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ shrdl %cl,%ebx,%edx
+ shrdl %cl,%eax,%ebx
+ movl %edx,8(%edi)
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ shrdl %cl,%edx,%eax
+ shrdl %cl,%ebx,%edx
+ movl %eax,16(%edi)
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ shrdl %cl,%eax,%ebx
+ shrdl %cl,%edx,%eax
+ movl %ebx,24(%edi)
+ movl %eax,28(%edi)
+
+ addl $32,%esi
+ addl $32,%edi
+ decl %ebp
+ jnz Roop
+
+Rend: popl %ebp
+ andl $7,%ebp
+ jz Rend2
+Roop2: movl (%esi),%eax
+ shrdl %cl,%eax,%edx /* compute result limb */
+ movl %edx,(%edi)
+ movl %eax,%edx
+ addl $4,%esi
+ addl $4,%edi
+ decl %ebp
+ jnz Roop2
+
+Rend2: shrl %cl,%edx /* compute most significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+Rspecial:
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ shrl $1,%edx
+ incl %ebp
+ decl %ebp
+ jz RLend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+RLoop: movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ rcrl $1,%eax
+ movl %ebx,(%edi)
+ rcrl $1,%edx
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ rcrl $1,%ebx
+ movl %edx,-8(%edi)
+ rcrl $1,%eax
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ rcrl $1,%edx
+ movl %eax,-16(%edi)
+ rcrl $1,%ebx
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ rcrl $1,%eax
+ movl %ebx,-24(%edi)
+ rcrl $1,%edx
+ movl %eax,-28(%edi)
+
+ leal -32(%esi),%esi /* use leal not to clobber carry */
+ leal -32(%edi),%edi
+ decl %ebp
+ jnz RLoop
+
+RLend: popl %ebp
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebp
+ jz RLend2
+ addl %eax,%eax /* restore carry from eax */
+RLoop2: movl %edx,%ebx
+ movl (%esi),%edx
+ rcrl $1,%edx
+ movl %ebx,(%edi)
+
+ leal -4(%esi),%esi /* use leal not to clobber carry */
+ leal -4(%edi),%edi
+ decl %ebp
+ jnz RLoop2
+
+ jmp RL1
+RLend2: addl %eax,%eax /* restore carry from eax */
+RL1: movl %edx,(%edi) /* store last limb */
+
+ movl $0,%eax
+ rcrl $1,%eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S
new file mode 100644
index 0000000..ef2d580
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S
@@ -0,0 +1,142 @@
+/* i80586 sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s1_ptr */
+ movl 28(%esp),%ebp /* s2_ptr */
+ movl 32(%esp),%ecx /* size */
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz Lend
+ pushl %edx
+
+ ALIGN (3)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L1: movl (%esi),%eax
+ movl 4(%esi),%edx
+ sbbl %ebx,%eax
+ movl 4(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L2: movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ sbbl %ebx,%eax
+ movl 12(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L3: movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ sbbl %ebx,%eax
+ movl 20(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L4: movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ sbbl %ebx,%eax
+ movl 28(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz Loop
+
+ popl %edx
+Lend:
+ decl %edx /* test %edx w/o clobbering carry */
+ js Lend2
+ incl %edx
+Loop2:
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ sbbl %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz Loop2
+Lend2:
+ movl (%esi),%eax
+ sbbl %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/longlong.h b/grub-core/lib/libgcrypt/mpi/longlong.h
new file mode 100644
index 0000000..5dba793
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/longlong.h
@@ -0,0 +1,1578 @@
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+ Note: I added some stuff for use with gnupg
+
+Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998,
+ 2000, 2001, 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with this file; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+/* You have to define the following before including this file:
+
+ UWtype -- An unsigned type, default type for operations (typically a "word")
+ UHWtype -- An unsigned type, at least half the size of UWtype.
+ UDWtype -- An unsigned type, at least twice as large a UWtype
+ W_TYPE_SIZE -- size in bits of UWtype
+
+ SItype, USItype -- Signed and unsigned 32 bit types.
+ DItype, UDItype -- Signed and unsigned 64 bit types.
+
+ On a 32 bit machine UWtype should typically be USItype;
+ on a 64 bit machine, UWtype should typically be UDItype.
+*/
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+/* This is used to make sure no undesirable sharing between different libraries
+ that use this file takes place. */
+#ifndef __MPN
+#define __MPN(x) __##x
+#endif
+
+/* Define auxiliary asm macros.
+
+ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
+ UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
+ word product in HIGH_PROD and LOW_PROD.
+
+ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
+ UDWtype product. This is just a variant of umul_ppmm.
+
+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator) divides a UDWtype, composed by the UWtype integers
+ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
+ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
+ than DENOMINATOR for correct operation. If, in addition, the most
+ significant bit of DENOMINATOR must be 1, then the pre-processor symbol
+ UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator). Like udiv_qrnnd but the numbers are signed. The quotient
+ is rounded towards 0.
+
+ 5) count_leading_zeros(count, x) counts the number of zero-bits from the
+ msb to the first non-zero bit in the UWtype X. This is the number of
+ steps X needs to be shifted left to set the msb. Undefined for X == 0,
+ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
+
+ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
+ from the least significant end.
+
+ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ high_addend_2, low_addend_2) adds two UWtype integers, composed by
+ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
+ (i.e. carry out) is not stored anywhere, and is lost.
+
+ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
+ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and is lost.
+
+ If any of these macros are left undefined for a particular CPU,
+ C macros are used. */
+
+/* The CPUs come in alphabetical order below.
+
+ Please add support for more CPUs here, or improve the current support
+ for the CPUs below! */
+
+#ifdef __riscos__
+#pragma continue_after_hash_error
+#else /* !__riscos__ */
+#if defined (__GNUC__) && !defined (NO_ASM)
+
+/* We sometimes need to clobber "cc" with gcc2, but that would not be
+ understood by gcc1. Use cpp to avoid major code duplication. */
+#if __GNUC__ < 2
+#define __CLOBBER_CC
+#define __AND_CLOBBER_CC
+#else /* __GNUC__ >= 2 */
+#define __CLOBBER_CC : "cc"
+#define __AND_CLOBBER_CC , "cc"
+#endif /* __GNUC__ < 2 */
+
+
+/***************************************
+ ************** A29K *****************
+ ***************************************/
+#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %1,%4,%5\n" \
+ "addc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %1,%4,%5\n" \
+ "subc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("multiplu %0,%1,%2" \
+ : "=r" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ __asm__ ("multmu %0,%1,%2" \
+ : "=r" ((USItype)(xh)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("dividu %0,%3,%4" \
+ : "=r" ((USItype)(q)), \
+ "=q" ((USItype)(r)) \
+ : "1" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+#define COUNT_LEADING_ZEROS_0 32
+#endif /* __a29k__ */
+
+
+#if defined (__alpha) && W_TYPE_SIZE == 64
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh %r1,%2,%0" \
+ : "=r" ((UDItype) ph) \
+ : "%rJ" (__m0), \
+ "rI" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 46
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UDItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UDItype __udiv_qrnnd ();
+#define UDIV_TIME 220
+#endif /* LONGLONG_STANDALONE */
+#endif /* __alpha */
+
+/***************************************
+ ************** ARM ******************
+ ***************************************/
+#if defined (__arm__) && W_TYPE_SIZE == 32 && !defined (__thumb__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5\n" \
+ "adc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5\n" \
+ "sbc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+ "mov %|r0, %2, lsr #16 @ AAAA\n" \
+ "mov %|r2, %3, lsr #16 @ BBBB\n" \
+ "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \
+ "bic %0, %3, %|r2, lsl #16 @ bbbb\n" \
+ "mul %1, %|r1, %|r2 @ aaaa * BBBB\n" \
+ "mul %|r2, %|r0, %|r2 @ AAAA * BBBB\n" \
+ "mul %|r1, %0, %|r1 @ aaaa * bbbb\n" \
+ "mul %0, %|r0, %0 @ AAAA * bbbb\n" \
+ "adds %|r0, %1, %0 @ central sum\n" \
+ "addcs %|r2, %|r2, #65536\n" \
+ "adds %1, %|r1, %|r0, lsl #16\n" \
+ "adc %0, %|r2, %|r0, lsr #16" \
+ : "=&r" ((USItype)(xh)), \
+ "=r" ((USItype)(xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
+ : "r0", "r1", "r2")
+#else
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+ "umull %r1, %r0, %r2, %r3" \
+ : "=&r" ((USItype)(xh)), \
+ "=r" ((USItype)(xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
+ : "r0", "r1")
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+/***************************************
+ ************** CLIPPER **************
+ ***************************************/
+#if defined (__clipper__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define smul_ppmm(w1, w0, u, v) \
+ ({union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("mulwx %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((SItype)(u)), \
+ "r" ((SItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__w) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ __w; })
+#endif /* __clipper__ */
+
+
+/***************************************
+ ************** GMICRO ***************
+ ***************************************/
+#if defined (__gmicro__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.w %5,%1\n" \
+ "addx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.w %5,%1\n" \
+ "subx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("mulx %3,%0,%1" \
+ : "=g" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%0" ((USItype)(m0)), \
+ "g" ((USItype)(m1)))
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("divx %4,%0,%1" \
+ : "=g" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "1" ((USItype)(nh)), \
+ "0" ((USItype)(nl)), \
+ "g" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bsch/1 %1,%0" \
+ : "=g" (count) \
+ : "g" ((USItype)(x)), \
+ "0" ((USItype)0))
+#endif
+
+
+/***************************************
+ ************** HPPA *****************
+ ***************************************/
+#if defined (__hppa) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ (" add %4,%5,%1\n" \
+ " addc %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "%rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ (" sub %4,%5,%1\n" \
+ " subb %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+#if defined (_PA_RISC1_1)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ (" xmpyu %1,%2,%0" \
+ : "=*f" (__xx.__ll) \
+ : "*f" ((USItype)(u)), \
+ "*f" ((USItype)(v))); \
+ (wh) = __xx.__i.__h; \
+ (wl) = __xx.__i.__l; \
+ } while (0)
+#define UMUL_TIME 8
+#define UDIV_TIME 60
+#else
+#define UMUL_TIME 40
+#define UDIV_TIME 80
+#endif
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { USItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern USItype __udiv_qrnnd ();
+#endif /* LONGLONG_STANDALONE */
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __tmp; \
+ __asm__ ( \
+ " ldi 1,%0 \n" \
+ " extru,= %1,15,16,%%r0 ; Bits 31..16 zero? \n" \
+ " extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \
+ " ldo 16(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,23,8,%%r0 ; Bits 15..8 zero? \n" \
+ " extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \
+ " ldo 8(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,27,4,%%r0 ; Bits 7..4 zero? \n" \
+ " extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \
+ " ldo 4(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,29,2,%%r0 ; Bits 3..2 zero? \n" \
+ " extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \
+ " ldo 2(%0),%0 ; Yes. Perform add. \n" \
+ " extru %1,30,1,%1 ; Extract bit 1. \n" \
+ " sub %0,%1,%0 ; Subtract it. " \
+ : "=r" (count), "=r" (__tmp) : "1" (x)); \
+ } while (0)
+#endif /* hppa */
+
+
+/***************************************
+ ************** I370 *****************
+ ***************************************/
+#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "r" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define smul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (m0), \
+ "r" (m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("dr %0,%2" \
+ : "=r" (__xx.__ll) \
+ : "0" (__xx.__ll), "r" (d)); \
+ (q) = __xx.__i.__l; (r) = __xx.__i.__h; \
+ } while (0)
+#endif
+
+
+/***************************************
+ ************** I386 *****************
+ ***************************************/
+#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl %5,%1\n" \
+ "adcl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl %5,%1\n" \
+ "sbbl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mull %3" \
+ : "=a" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "rm" ((USItype)(v)))
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divl %4" \
+ : "=a" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "rm" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("bsrl %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define count_trailing_zeros(count, x) \
+ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
+#ifndef UMUL_TIME
+#define UMUL_TIME 40
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME 40
+#endif
+#endif /* 80x86 */
+
+
+/***************************************
+ ************** I860 *****************
+ ***************************************/
+#if defined (__i860__) && W_TYPE_SIZE == 32
+#define rshift_rhlc(r,h,l,c) \
+ __asm__ ("shr %3,r0,r0\n" \
+ "shrd %1,%2,%0" \
+ "=r" (r) : "r" (h), "r" (l), "rn" (c))
+#endif /* i860 */
+
+/***************************************
+ ************** I960 *****************
+ ***************************************/
+#if defined (__i960__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 1,0\n" \
+ "addc %5,%4,%1\n" \
+ "addc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "%dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 0,0\n" \
+ "subc %5,%4,%1\n" \
+ "subc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__xx.__ll) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__w) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (nh); __nn.__i.__l = (nl); \
+ __asm__ ("ediv %d,%n,%0" \
+ : "=d" (__rq.__ll) \
+ : "dI" (__nn.__ll), \
+ "dI" ((USItype)(d))); \
+ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("scanbit %1,%0" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
+#if defined (__i960mx) /* what is the proper symbol to test??? */
+#define rshift_rhlc(r,h,l,c) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (h); __nn.__i.__l = (l); \
+ __asm__ ("shre %2,%1,%0" \
+ : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
+ }
+#endif /* i960mx */
+#endif /* i960 */
+
+
+/***************************************
+ ************** 68000 ****************
+ ***************************************/
+#if (defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%.l %5,%1\n" \
+ "addx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%.l %5,%1\n" \
+ "subx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulu%.l %3,%1:%0" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "dmi" ((USItype)(v)))
+#define UMUL_TIME 45
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divu%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+#define UDIV_TIME 90
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divs%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bfffo %1{%b2:%b2},%0" \
+ : "=d" ((USItype)(count)) \
+ : "od" ((USItype)(x)), "n" (0))
+#define COUNT_LEADING_ZEROS_0 32
+#else /* not mc68020 */
+#define umul_ppmm(xh, xl, a, b) \
+ do { USItype __umul_tmp1, __umul_tmp2; \
+ __asm__ ("| Inlined umul_ppmm \n" \
+ " move%.l %5,%3 \n" \
+ " move%.l %2,%0 \n" \
+ " move%.w %3,%1 \n" \
+ " swap %3 \n" \
+ " swap %0 \n" \
+ " mulu %2,%1 \n" \
+ " mulu %3,%0 \n" \
+ " mulu %2,%3 \n" \
+ " swap %2 \n" \
+ " mulu %5,%2 \n" \
+ " add%.l %3,%2 \n" \
+ " jcc 1f \n" \
+ " add%.l %#0x10000,%0 \n" \
+ "1: move%.l %2,%3 \n" \
+ " clr%.w %2 \n" \
+ " swap %2 \n" \
+ " swap %3 \n" \
+ " clr%.w %3 \n" \
+ " add%.l %3,%1 \n" \
+ " addx%.l %2,%0 \n" \
+ " | End inlined umul_ppmm" \
+ : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \
+ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
+ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
+ } while (0)
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#endif /* not mc68020 */
+#endif /* mc68000 */
+
+
+/***************************************
+ ************** 88000 ****************
+ ***************************************/
+#if defined (__m88000__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addu.co %1,%r4,%r5\n" \
+ "addu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subu.co %1,%r4,%r5\n" \
+ "subu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("ff1 %0,%1" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 63 /* sic */
+#if defined (__m88110__)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x, __q; \
+ __x.__i.__h = (n1); __x.__i.__l = (n0); \
+ __asm__ ("divu.d %0,%1,%2" \
+ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
+ (r) = (n0) - __q.__l * (d); (q) = __q.__l; })
+#define UMUL_TIME 5
+#define UDIV_TIME 25
+#else
+#define UMUL_TIME 17
+#define UDIV_TIME 150
+#endif /* __m88110__ */
+#endif /* __m88000__ */
+
+/***************************************
+ ************** MIPS *****************
+ ***************************************/
+#if defined (__mips__) && W_TYPE_SIZE == 32
+#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UDItype _r; \
+ _r = (UDItype) u * v; \
+ (w1) = _r >> 32; \
+ (w0) = (USItype) _r; \
+ } while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3" \
+ : "=l" ((USItype)(w0)), \
+ "=h" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3 \n" \
+ "mflo %0 \n" \
+ "mfhi %1" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#endif
+#define UMUL_TIME 10
+#define UDIV_TIME 100
+#endif /* __mips__ */
+
+/***************************************
+ ************** MIPS/64 **************
+ ***************************************/
+#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UTItype _r; \
+ _r = (UTItype) u * v; \
+ (w1) = _r >> 64; \
+ (w0) = (UDItype) _r; \
+ } while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" \
+ : "=l" ((UDItype)(w0)), \
+ "=h" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3 \n" \
+ "mflo %0 \n" \
+ "mfhi %1" \
+ : "=d" ((UDItype)(w0)), \
+ "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 140
+#endif /* __mips__ */
+
+
+/***************************************
+ ************** 32000 ****************
+ ***************************************/
+#if defined (__ns32000__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__w) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
+ __asm__ ("deid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "0" (__xx.__ll), \
+ "g" ((USItype)(d))); \
+ (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
+#define count_trailing_zeros(count,x) \
+ do {
+ __asm__ ("ffsd %2,%0" \
+ : "=r" ((USItype) (count)) \
+ : "0" ((USItype) 0), \
+ "r" ((USItype) (x))); \
+ } while (0)
+#endif /* __ns32000__ */
+
+
+/***************************************
+ ************** PPC ******************
+ ***************************************/
+#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("{cntlz|cntlzw} %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+#define COUNT_LEADING_ZEROS_0 32
+#if defined (_ARCH_PPC)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhwu %0,%1,%2" \
+ : "=r" ((USItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ SItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhw %0,%1,%2" \
+ : "=r" ((SItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14
+#define UDIV_TIME 120
+#else
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((USItype)(xh)), \
+ "=q" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define UMUL_TIME 8
+#define smul_ppmm(xh, xl, m0, m1) \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((SItype)(xh)), \
+ "=q" ((SItype)(xl)) \
+ : "r" (m0), \
+ "r" (m1))
+#define SMUL_TIME 4
+#define sdiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("div %0,%2,%4" \
+ : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \
+ : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d)))
+#define UDIV_TIME 100
+#endif
+#endif /* Power architecture variants. */
+
+/* Powerpc 64 bit support taken from gmp-4.1.2. */
+/* We should test _IBMR2 here when we add assembly support for the system
+ vendor compilers. */
+#if 0 /* Not yet enabled because we don't have hardware for a test. */
+#if (defined (_ARCH_PPC) || defined (__powerpc__)) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 64
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ DItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14 /* ??? */
+#define UDIV_TIME 120 /* ??? */
+#endif /* 64-bit PowerPC. */
+#endif /* if 0 */
+
+/***************************************
+ ************** PYR ******************
+ ***************************************/
+#if defined (__pyr__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addw %5,%1 \n" \
+ "addwc %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subw %5,%1 \n" \
+ "subwb %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("movw %1,%R0 \n" \
+ "uemul %2,%0" \
+ : "=&r" (__xx.__ll) \
+ : "g" ((USItype) (u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#endif /* __pyr__ */
+
+
+/***************************************
+ ************** RT/ROMP **************
+ ***************************************/
+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("a %1,%5 \n" \
+ "ae %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("s %1,%5\n" \
+ "se %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ( \
+ "s r2,r2 \n" \
+ "mts r10,%2 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "cas %0,r2,r0 \n" \
+ "mfs r10,%1" \
+ : "=r" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%r" (__m0), \
+ "r" (__m1) \
+ : "r2"); \
+ (ph) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define UMUL_TIME 20
+#define UDIV_TIME 200
+#define count_leading_zeros(count, x) \
+ do { \
+ if ((x) >= 0x10000) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x) >> 16)); \
+ else \
+ { \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x))); \
+ (count) += 16; \
+ } \
+ } while (0)
+#endif /* RT/ROMP */
+
+
+/***************************************
+ ************** SH2 ******************
+ ***************************************/
+#if (defined (__sh2__) || defined(__sh3__) || defined(__SH4__) ) \
+ && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ( \
+ "dmulu.l %2,%3\n" \
+ "sts macl,%1\n" \
+ "sts mach,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "macl", "mach")
+#define UMUL_TIME 5
+#endif
+
+/***************************************
+ ************** SPARC ****************
+ ***************************************/
+#if defined (__sparc__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addcc %r4,%5,%1\n" \
+ "addx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subcc %r4,%5,%1\n" \
+ "subx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+#if defined (__sparc_v8__)
+/* Don't match immediate range because, 1) it is not often useful,
+ 2) the 'I' flag thinks of the range as a 13 bit signed interval,
+ while we want to match a 13 bit interval, sign extended to 32 bits,
+ but INTERPRETED AS UNSIGNED. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+#define UMUL_TIME 5
+#ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" ((USItype)(__q)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d))); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+ } while (0)
+#define UDIV_TIME 25
+#endif /* SUPERSPARC */
+#else /* ! __sparc_v8__ */
+#if defined (__sparclite__)
+/* This has hardware multiply but not divide. It also has two additional
+ instructions scan (ffs from high bit) and divscc. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+#define UMUL_TIME 5
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("! Inlined udiv_qrnnd \n" \
+ " wr %%g0,%2,%%y ! Not a delayed write for sparclite \n" \
+ " tst %%g0 \n" \
+ " divscc %3,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%0 \n" \
+ " rd %%y,%1 \n" \
+ " bl,a 1f \n" \
+ " add %1,%4,%1 \n" \
+ "1: ! End of inline udiv_qrnnd" \
+ : "=r" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "rI" ((USItype)(d)) \
+ : "%g1" __AND_CLOBBER_CC)
+#define UDIV_TIME 37
+#define count_leading_zeros(count, x) \
+ __asm__ ("scan %1,0,%0" \
+ : "=r" ((USItype)(x)) \
+ : "r" ((USItype)(count)))
+/* Early sparclites return 63 for an argument of 0, but they warn that future
+ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
+ undefined. */
+#endif /* __sparclite__ */
+#endif /* __sparc_v8__ */
+/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
+#ifndef umul_ppmm
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("! Inlined umul_ppmm \n" \
+ " wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr \n" \
+ " sra %3,31,%%g2 ! Don't move this insn \n" \
+ " and %2,%%g2,%%g2 ! Don't move this insn \n" \
+ " andcc %%g0,0,%%g1 ! Don't move this insn \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,0,%%g1 \n" \
+ " add %%g1,%%g2,%0 \n" \
+ " rd %%y,%1" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "%rI" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "%g1", "%g2" __AND_CLOBBER_CC)
+#define UMUL_TIME 39 /* 39 instructions */
+#endif
+#ifndef udiv_qrnnd
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { USItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern USItype __udiv_qrnnd ();
+#define UDIV_TIME 140
+#endif /* LONGLONG_STANDALONE */
+#endif /* udiv_qrnnd */
+#endif /* __sparc__ */
+
+
+/***************************************
+ ************** VAX ******************
+ ***************************************/
+#if defined (__vax__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl2 %5,%1\n" \
+ "adwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl2 %5,%1\n" \
+ "sbwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("emul %1,%2,$0,%0" \
+ : "=g" (__xx.__ll) \
+ : "g" (__m0), \
+ "g" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("ediv %3,%2,%0,%1" \
+ : "=g" (q), "=g" (r) \
+ : "g" (__xx.__ll), "g" (d)); \
+ } while (0)
+#endif /* __vax__ */
+
+
+/***************************************
+ ************** Z8000 ****************
+ ***************************************/
+#if defined (__z8000__) && W_TYPE_SIZE == 16
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "%0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "%1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {long int __ll; \
+ struct {unsigned int __h, __l;} __i; \
+ } __xx; \
+ unsigned int __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mult %S0,%H3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "rQR" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ + (((signed int) __m1 >> 15) & __m0)); \
+ } while (0)
+#endif /* __z8000__ */
+
+#endif /* __GNUC__ */
+#endif /* !__riscos__ */
+
+
+/***************************************
+ *********** Generic Versions ********
+ ***************************************/
+#if !defined (umul_ppmm) && defined (__umulsidi3)
+#define umul_ppmm(ph, pl, m0, m1) \
+ { \
+ UDWtype __ll = __umulsidi3 (m0, m1); \
+ ph = (UWtype) (__ll >> W_TYPE_SIZE); \
+ pl = (UWtype) __ll; \
+ }
+#endif
+
+#if !defined (__umulsidi3)
+#define __umulsidi3(u, v) \
+ ({UWtype __hi, __lo; \
+ umul_ppmm (__hi, __lo, u, v); \
+ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
+#endif
+
+/* If this machine has no inline assembler, use C macros. */
+
+#if !defined (add_ssaaaa)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) + (bl); \
+ (sh) = (ah) + (bh) + (__x < (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (sub_ddmmss)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - (__x > (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ UWtype __u = (u), __v = (v); \
+ \
+ __ul = __ll_lowpart (__u); \
+ __uh = __ll_highpart (__u); \
+ __vl = __ll_lowpart (__v); \
+ __vh = __ll_highpart (__v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
+ } while (0)
+#endif
+
+#if !defined (umul_ppmm)
+#define smul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __w1; \
+ UWtype __m0 = (u), __m1 = (v); \
+ umul_ppmm (__w1, w0, __m0, __m1); \
+ (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
+ - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
+ } while (0)
+#endif
+
+/* Define this unconditionally, so it can be used for debugging. */
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
+ __d1 = __ll_highpart (d); \
+ __d0 = __ll_lowpart (d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (UWtype) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (UWtype) __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (UWtype) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+ __udiv_w_sdiv (defined in libgcc or elsewhere). */
+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ UWtype __r; \
+ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
+ (r) = __r; \
+ } while (0)
+#endif
+
+/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
+#if !defined (udiv_qrnnd)
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+#endif
+
+#if !defined (count_leading_zeros)
+extern
+#ifdef __STDC__
+const
+#endif
+unsigned char _gcry_clz_tab[];
+#define MPI_INTERNAL_NEED_CLZ_TAB 1
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype __xr = (x); \
+ UWtype __a; \
+ \
+ if (W_TYPE_SIZE <= 32) \
+ { \
+ __a = __xr < ((UWtype) 1 << 2*__BITS4) \
+ ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
+ : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\
+ } \
+ else \
+ { \
+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ } \
+ \
+ (count) = W_TYPE_SIZE - (_gcry_clz_tab[__xr >> __a] + __a); \
+ } while (0)
+/* This version gives a well-defined value for zero. */
+#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
+#endif
+
+#if !defined (count_trailing_zeros)
+/* Define count_trailing_zeros using count_leading_zeros. The latter might be
+ defined in asm, but if it is not, the C version above is good enough. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ UWtype __ctz_c; \
+ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
+ (count) = W_TYPE_SIZE - 1 - __ctz_c; \
+ } while (0)
+#endif
+
+#ifndef UDIV_NEEDS_NORMALIZATION
+#define UDIV_NEEDS_NORMALIZATION 0
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/Manifest b/grub-core/lib/libgcrypt/mpi/m68k/Manifest
new file mode 100644
index 0000000..8e0538a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/Manifest
@@ -0,0 +1,25 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+syntax.h
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+mpih-sub1.S
+$names$ iQCVAwUAP+LmTDEAnp832S/7AQJHUAP/dxfq2U0pDc5ZLoEizoqgjjcnHIyb9EjMG3YjvgK6jQ62yoAOCuo/jFYlJS+Mdve6bgfdTzYMrnKV7BG2SEcwb263pVnIntS7ZhKQPiMCbFgXWR2VjN3+a1v8yjQDZtgqEgm8OlQ+u7jKBY13Oryiuq5nPNxsXZqJpelG6Zkdg9M==PIee
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/distfiles b/grub-core/lib/libgcrypt/mpi/m68k/distfiles
new file mode 100644
index 0000000..1e2e36f
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/distfiles
@@ -0,0 +1,9 @@
+Manifest
+syntax.h
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+mpih-sub1.S
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest
new file mode 100644
index 0000000..bcb2768
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest
@@ -0,0 +1,23 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+$names$ iQCVAwUAP+LmRTEAnp832S/7AQK3rwP/TyGBbii5HCrjDiLCVJHiDNeOdENx6AicRXnu4vuJmMmPZ0y+i7MPusDaeTbIUA0w6RaJx+Ep41nIvthmNDnFePY5Mw0pIUJcpI7AJR4vYqpwNQA6nlEdn/m1jg6sPLKZXUXNUkhroEzcHzoU+12BPS+nvSXlwSksg6rXEGOJ+Ms==XCXP
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles
new file mode 100644
index 0000000..6b96433
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles
@@ -0,0 +1,4 @@
+Manifest
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S
new file mode 100644
index 0000000..007c94c
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S
@@ -0,0 +1,104 @@
+/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+PROLOG(_gcry_mpih_mul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d4),MEM_PREDEC(sp)
+#if 0
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(d3),MEM_PREDEC(sp)
+ movel R(d4),MEM_PREDEC(sp)
+#endif
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,16),R(res_ptr)
+ movel MEM_DISP(sp,20),R(s1_ptr)
+ movel MEM_DISP(sp,24),R(s1_size)
+ movel MEM_DISP(sp,28),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ movel R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ movel R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ clrl R(d3)
+ addxl R(d3),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d4)
+#if 0
+ movel MEM_POSTINC(sp),R(d4)
+ movel MEM_POSTINC(sp),R(d3)
+ movel MEM_POSTINC(sp),R(d2)
+#endif
+ rts
+EPILOG(_gcry_mpih_mul_1)
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S
new file mode 100644
index 0000000..44baa8d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S
@@ -0,0 +1,94 @@
+/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+PROLOG(_gcry_mpih_addmul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d5),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,20),R(res_ptr)
+ movel MEM_DISP(sp,24),R(s1_ptr)
+ movel MEM_DISP(sp,28),R(s1_size)
+ movel MEM_DISP(sp,32),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ clrl R(d5)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ addxl R(d5),R(d1)
+ addl R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ addxl R(d5),R(d0)
+ addl R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ addxl R(d5),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d5)
+
+ rts
+EPILOG(_gcry_mpih_addmul_1)
+
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S
new file mode 100644
index 0000000..e958ef6
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S
@@ -0,0 +1,97 @@
+/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+PROLOG(_gcry_mpih_submul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d5),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,20),R(res_ptr)
+ movel MEM_DISP(sp,24),R(s1_ptr)
+ movel MEM_DISP(sp,28),R(s1_size)
+ movel MEM_DISP(sp,32),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ clrl R(d5)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ addxl R(d5),R(d1)
+ subl R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ addxl R(d5),R(d0)
+ subl R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ addxl R(d5),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d5)
+
+ rts
+EPILOG(_gcry_mpih_submul_1)
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S
new file mode 100644
index 0000000..8182d21
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S
@@ -0,0 +1,92 @@
+/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994,1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 16)
+ * mpi_size_t size) (sp + 12)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n)
+
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+PROLOG(_gcry_mpih_add_n)
+ /* Save used registers on the stack. */
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,12),R(a2)
+ movel MEM_DISP(sp,16),R(a0)
+ movel MEM_DISP(sp,20),R(a1)
+ movel MEM_DISP(sp,24),R(d2)
+
+ eorw #1,R(d2)
+ lsrl #1,R(d2)
+ bcc L(L1)
+ subql #1,R(d2) /* clears cy as side effect */
+
+L(Loop:)
+ movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ addxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+L(L1:) movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ addxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+
+ dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */
+ subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */
+ subl #0x10000,R(d2)
+ bcs L(L2)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(Loop)
+
+L(L2:)
+ negl R(d0)
+
+ /* Restore used registers from stack frame. */
+ movel MEM_POSTINC(sp),R(a2)
+ movel MEM_POSTINC(sp),R(d2)
+
+ rts
+EPILOG(_gcry_mpih_add_n)
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S
new file mode 100644
index 0000000..133d1aa
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S
@@ -0,0 +1,164 @@
+/* mc68020 lshift -- Shift left a low-level natural-number integer.
+ *
+ * Copyright (C) 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+#define res_ptr a1
+#define s_ptr a0
+#define s_size d6
+#define cnt d4
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_lshift)
+
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+PROLOG(_gcry_mpih_lshift)
+
+ /* Save used registers on the stack. */
+ moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. */
+ movel MEM_DISP(sp,28),R(res_ptr)
+ movel MEM_DISP(sp,32),R(s_ptr)
+ movel MEM_DISP(sp,36),R(s_size)
+ movel MEM_DISP(sp,40),R(cnt)
+
+ moveql #1,R(d5)
+ cmpl R(d5),R(cnt)
+ bne L(Lnormal)
+ cmpl R(s_ptr),R(res_ptr)
+ bls L(Lspecial) /* jump if s_ptr >= res_ptr */
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(a2)
+#else /* not mc68020 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ lea MEM_INDX(s_ptr,d0,l),R(a2)
+#endif
+ cmpl R(res_ptr),R(a2)
+ bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */
+
+L(Lnormal:)
+ moveql #32,R(d5)
+ subl R(cnt),R(d5)
+
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
+#else /* not mc68000 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ addl R(s_size),R(s_ptr)
+ addl R(s_size),R(res_ptr)
+#endif
+ movel MEM_PREDEC(s_ptr),R(d2)
+ movel R(d2),R(d0)
+ lsrl R(d5),R(d0) /* compute carry limb */
+
+ lsll R(cnt),R(d2)
+ movel R(d2),R(d1)
+ subql #1,R(s_size)
+ beq L(Lend)
+ lsrl #1,R(s_size)
+ bcs L(L1)
+ subql #1,R(s_size)
+
+L(Loop:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ movel R(d2),R(d3)
+ lsrl R(d5),R(d3)
+ orl R(d3),R(d1)
+ movel R(d1),MEM_PREDEC(res_ptr)
+ lsll R(cnt),R(d2)
+L(L1:)
+ movel MEM_PREDEC(s_ptr),R(d1)
+ movel R(d1),R(d3)
+ lsrl R(d5),R(d3)
+ orl R(d3),R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+ lsll R(cnt),R(d1)
+
+ dbf R(s_size),L(Loop)
+ subl #0x10000,R(s_size)
+ bcc L(Loop)
+
+L(Lend:)
+ movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination. */
+
+L(Lspecial:)
+ clrl R(d0) /* initialize carry */
+ eorw #1,R(s_size)
+ lsrl #1,R(s_size)
+ bcc L(LL1)
+ subql #1,R(s_size)
+
+L(LLoop:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ addxl R(d2),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+L(LL1:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ addxl R(d2),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+
+ dbf R(s_size),L(LLoop)
+ addxl R(d0),R(d0) /* save cy in lsb */
+ subl #0x10000,R(s_size)
+ bcs L(LLend)
+ lsrl #1,R(d0) /* restore cy */
+ bra L(LLoop)
+
+L(LLend:)
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+EPILOG(_gcry_mpih_lshift)
+
+
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S
new file mode 100644
index 0000000..be9f435
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S
@@ -0,0 +1,162 @@
+/* mc68020 rshift -- Shift right a low-level natural-number integer.
+ *
+ * Copyright (C) 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+#define res_ptr a1
+#define s_ptr a0
+#define s_size d6
+#define cnt d4
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_rshift)
+
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+PROLOG(_gcry_mpih_rshift)
+ /* Save used registers on the stack. */
+ moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. */
+ movel MEM_DISP(sp,28),R(res_ptr)
+ movel MEM_DISP(sp,32),R(s_ptr)
+ movel MEM_DISP(sp,36),R(s_size)
+ movel MEM_DISP(sp,40),R(cnt)
+
+ moveql #1,R(d5)
+ cmpl R(d5),R(cnt)
+ bne L(Rnormal)
+ cmpl R(res_ptr),R(s_ptr)
+ bls L(Rspecial) /* jump if res_ptr >= s_ptr */
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(a2)
+#else /* not mc68020 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ lea MEM_INDX(res_ptr,d0,l),R(a2)
+#endif
+ cmpl R(s_ptr),R(a2)
+ bls L(Rspecial) /* jump if s_ptr >= res_ptr + s_size */
+
+L(Rnormal:)
+ moveql #32,R(d5)
+ subl R(cnt),R(d5)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ movel R(d2),R(d0)
+ lsll R(d5),R(d0) /* compute carry limb */
+
+ lsrl R(cnt),R(d2)
+ movel R(d2),R(d1)
+ subql #1,R(s_size)
+ beq L(Rend)
+ lsrl #1,R(s_size)
+ bcs L(R1)
+ subql #1,R(s_size)
+
+L(Roop:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ movel R(d2),R(d3)
+ lsll R(d5),R(d3)
+ orl R(d3),R(d1)
+ movel R(d1),MEM_POSTINC(res_ptr)
+ lsrl R(cnt),R(d2)
+L(R1:)
+ movel MEM_POSTINC(s_ptr),R(d1)
+ movel R(d1),R(d3)
+ lsll R(d5),R(d3)
+ orl R(d3),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+ lsrl R(cnt),R(d1)
+
+ dbf R(s_size),L(Roop)
+ subl #0x10000,R(s_size)
+ bcc L(Roop)
+
+L(Rend:)
+ movel R(d1),MEM(res_ptr) /* store most significant limb */
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+
+/* We loop from most significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination. */
+
+L(Rspecial:)
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
+#else /* not mc68000 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ addl R(s_size),R(s_ptr)
+ addl R(s_size),R(res_ptr)
+#endif
+
+ clrl R(d0) /* initialize carry */
+ eorw #1,R(s_size)
+ lsrl #1,R(s_size)
+ bcc L(LR1)
+ subql #1,R(s_size)
+
+L(LRoop:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ roxrl #1,R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+L(LR1:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ roxrl #1,R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+
+ dbf R(s_size),L(LRoop)
+ roxrl #1,R(d0) /* save cy in msb */
+ subl #0x10000,R(s_size)
+ bcs L(LRend)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(LRoop)
+
+L(LRend:)
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+EPILOG(_gcry_mpih_rshift)
+
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S
new file mode 100644
index 0000000..ee7555f
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S
@@ -0,0 +1,91 @@
+/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 16)
+ * mpi_size_t size) (sp + 12)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_sub_n)
+
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+PROLOG(_gcry_mpih_sub_n)
+/* Save used registers on the stack. */
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(a2),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,12),R(a2)
+ movel MEM_DISP(sp,16),R(a0)
+ movel MEM_DISP(sp,20),R(a1)
+ movel MEM_DISP(sp,24),R(d2)
+
+ eorw #1,R(d2)
+ lsrl #1,R(d2)
+ bcc L(L1)
+ subql #1,R(d2) /* clears cy as side effect */
+
+L(Loop:)
+ movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ subxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+L(L1:) movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ subxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+
+ dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */
+ subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */
+ subl #0x10000,R(d2)
+ bcs L(L2)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(Loop)
+
+L(L2:)
+ negl R(d0)
+
+/* Restore used registers from stack frame. */
+ movel MEM_POSTINC(sp),R(a2)
+ movel MEM_POSTINC(sp),R(d2)
+
+ rts
+EPILOG(_gcry_mpih_sub_n)
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/m68k/syntax.h b/grub-core/lib/libgcrypt/mpi/m68k/syntax.h
new file mode 100644
index 0000000..e27de98
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/m68k/syntax.h
@@ -0,0 +1,185 @@
+/* asm.h -- Definitions for 68k syntax variations.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#undef ALIGN
+
+#ifdef MIT_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)base@
+#define MEM_DISP(base,displacement)base@(displacement)
+#define MEM_INDX(base,idx,size_suffix)base@(idx:size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)base@(idx:size_suffix:scale)
+#define MEM_PREDEC(memory_base)memory_base@-
+#define MEM_POSTINC(memory_base)memory_base@+
+#define L(label) label
+#define TEXT .text
+#define ALIGN .even
+#define GLOBL .globl
+#define moveql moveq
+/* Use variable sized opcodes. */
+#define bcc jcc
+#define bcs jcs
+#define bls jls
+#define beq jeq
+#define bne jne
+#define bra jra
+#endif
+
+#ifdef SONY_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)(displacement,base)
+#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale)
+#define MEM_PREDEC(memory_base)-(memory_base)
+#define MEM_POSTINC(memory_base)(memory_base)+
+#define L(label) label
+#define TEXT .text
+#define ALIGN .even
+#define GLOBL .globl
+#endif
+
+#ifdef MOTOROLA_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)(displacement,base)
+#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale)
+#define MEM_PREDEC(memory_base)-(memory_base)
+#define MEM_POSTINC(memory_base)(memory_base)+
+#define L(label) label
+#define TEXT
+#define ALIGN
+#define GLOBL XDEF
+#define lea LEA
+#define movel MOVE.L
+#define moveml MOVEM.L
+#define moveql MOVEQ.L
+#define cmpl CMP.L
+#define orl OR.L
+#define clrl CLR.L
+#define eorw EOR.W
+#define lsrl LSR.L
+#define lsll LSL.L
+#define roxrl ROXR.L
+#define roxll ROXL.L
+#define addl ADD.L
+#define addxl ADDX.L
+#define addql ADDQ.L
+#define subl SUB.L
+#define subxl SUBX.L
+#define subql SUBQ.L
+#define negl NEG.L
+#define mulul MULU.L
+#define bcc BCC
+#define bcs BCS
+#define bls BLS
+#define beq BEQ
+#define bne BNE
+#define bra BRA
+#define dbf DBF
+#define rts RTS
+#define d0 D0
+#define d1 D1
+#define d2 D2
+#define d3 D3
+#define d4 D4
+#define d5 D5
+#define d6 D6
+#define d7 D7
+#define a0 A0
+#define a1 A1
+#define a2 A2
+#define a3 A3
+#define a4 A4
+#define a5 A5
+#define a6 A6
+#define a7 A7
+#define sp SP
+#endif
+
+#ifdef ELF_SYNTAX
+#define PROLOG(name) .type name,@function
+#define EPILOG(name) .size name,.-name
+#define MEM(base)(R(base))
+#define MEM_DISP(base,displacement)(displacement,R(base))
+#define MEM_PREDEC(memory_base)-(R(memory_base))
+#define MEM_POSTINC(memory_base)(R(memory_base))+
+#ifdef __STDC__
+#define R_(r)%##r
+#define R(r)R_(r)
+#define MEM_INDX_(base,idx,size_suffix)(R(base),R(idx##.##size_suffix))
+#define MEM_INDX(base,idx,size_suffix)MEM_INDX_(base,idx,size_suffix)
+#define MEM_INDX1_(base,idx,size_suffix,scale)(R(base),R(idx##.##size_suffix*scale))
+#define MEM_INDX1(base,idx,size_suffix,scale)MEM_INDX1_(base,idx,size_suffix,scale)
+#define L(label) .##label
+#else
+#define R(r)%/**/r
+#define MEM_INDX(base,idx,size_suffix)(R(base),R(idx).size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(R(base),R(idx).size_suffix*scale)
+#define L(label) ./**/label
+#endif
+#define TEXT .text
+#define ALIGN .align 2
+#define GLOBL .globl
+#define bcc jbcc
+#define bcs jbcs
+#define bls jbls
+#define beq jbeq
+#define bne jbne
+#define bra jbra
+#endif
+
+#if defined (SONY_SYNTAX) || defined (ELF_SYNTAX)
+#define movel move.l
+#define moveml movem.l
+#define moveql moveq.l
+#define cmpl cmp.l
+#define orl or.l
+#define clrl clr.l
+#define eorw eor.w
+#define lsrl lsr.l
+#define lsll lsl.l
+#define roxrl roxr.l
+#define roxll roxl.l
+#define addl add.l
+#define addxl addx.l
+#define addql addq.l
+#define subl sub.l
+#define subxl subx.l
+#define subql subq.l
+#define negl neg.l
+#define mulul mulu.l
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/Manifest b/grub-core/lib/libgcrypt/mpi/mips3/Manifest
new file mode 100644
index 0000000..e191184
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/Manifest
@@ -0,0 +1,28 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpi-asm-defs.h
+$names$ iQCVAwUAP+LmUTEAnp832S/7AQLm/gP/RHR2aLMwHPxsq0mGO5H0kneVn8a9l9yDNEZBefkYcOJMb7MZGKxbGspyENiU04Mc2TFnA1wS9gjNHlRWtUYxxn/wyuV6BIRgfstXt2nXGgEQrK07GIz8ETFcYqcxu7JKiICIuXZgnIgdwBJswbBV1zaMUDXeg5B8vkkEeRWj8hQ==IQVO
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/README b/grub-core/lib/libgcrypt/mpi/mips3/README
new file mode 100644
index 0000000..e94b2c7
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/README
@@ -0,0 +1,23 @@
+This directory contains mpn functions optimized for MIPS3. Example of
+processors that implement MIPS3 are R4000, R4400, R4600, R4700, and R8000.
+
+RELEVANT OPTIMIZATION ISSUES
+
+1. On the R4000 and R4400, branches, both the plain and the "likely" ones,
+ take 3 cycles to execute. (The fastest possible loop will take 4 cycles,
+ because of the delay insn.)
+
+ On the R4600, branches takes a single cycle
+
+ On the R8000, branches often take no noticable cycles, as they are
+ executed in a separate function unit..
+
+2. The R4000 and R4400 have a load latency of 4 cycles.
+
+3. On the R4000 and R4400, multiplies take a data-dependent number of
+ cycles, contrary to the SGI documentation. There seem to be 3 or 4
+ possible latencies.
+
+STATUS
+
+Good...
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/distfiles b/grub-core/lib/libgcrypt/mpi/mips3/distfiles
new file mode 100644
index 0000000..ef9b6fe
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/distfiles
@@ -0,0 +1,11 @@
+Manifest
+README
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpi-asm-defs.h
+
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h b/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h
new file mode 100644
index 0000000..2d9a9c1
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h
@@ -0,0 +1,10 @@
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB 8
+
+
+
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S
new file mode 100644
index 0000000..f3db029
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S
@@ -0,0 +1,124 @@
+/* mips3 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($4)
+ * mpi_ptr_t s1_ptr, ($5)
+ * mpi_ptr_t s2_ptr, ($6)
+ * mpi_size_t size) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_add_n
+ .ent _gcry_mpih_add_n
+_gcry_mpih_add_n:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$2
+ ld $11,16($6)
+ sltu $8,$13,$2
+ daddu $13,$12,$13
+ sltu $2,$13,$12
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$2
+ ld $13,24($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$2
+ ld $11,32($6)
+ sltu $8,$13,$2
+ daddu $13,$12,$13
+ sltu $2,$13,$12
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+
+ .end _gcry_mpih_add_n
+
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S
new file mode 100644
index 0000000..084c109
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S
@@ -0,0 +1,97 @@
+/* mips3 lshift
+ *
+ * Copyright (C) 1995, 1998, 2000,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, ($4)
+ * mpi_ptr_t up, ($5)
+ * mpi_size_t usize, ($6)
+ * unsigned cnt) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_lshift
+ .ent _gcry_mpih_lshift
+_gcry_mpih_lshift:
+ .set noreorder
+ .set nomacro
+
+ dsll $2,$6,3
+ daddu $5,$5,$2 # make r5 point at end of src
+ ld $10,-8($5) # load first limb
+ dsubu $13,$0,$7
+ daddu $4,$4,$2 # make r4 point at end of res
+ daddiu $6,$6,-1
+ and $9,$6,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ dsrl $2,$10,$13 # compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,-16($5)
+ daddiu $4,$4,-8
+ daddiu $5,$5,-8
+ daddiu $9,$9,-1
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,0($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,-16($5)
+ daddiu $4,$4,-32
+ daddiu $6,$6,-4
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+
+ ld $10,-24($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,24($4)
+ dsrl $9,$10,$13
+
+ ld $3,-32($5)
+ dsll $11,$10,$7
+ or $8,$14,$9
+ sd $8,16($4)
+ dsrl $12,$3,$13
+
+ ld $10,-40($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,8($4)
+ dsrl $9,$10,$13
+
+ daddiu $5,$5,-32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,0($4)
+
+.Lend: dsll $8,$10,$7
+ j $31
+ sd $8,-8($4)
+ .end _gcry_mpih_lshift
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S
new file mode 100644
index 0000000..6c0099d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S
@@ -0,0 +1,89 @@
+/* mips3 mpih-mul1.S -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_mul_1
+ .ent _gcry_mpih_mul_1
+_gcry_mpih_mul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: mflo $10
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $10,$10,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$10,$2 # carry from previous addition -> $2
+ sd $10,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ dmultu $8,$7
+ sd $10,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ sd $10,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_mul_1
+
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S
new file mode 100644
index 0000000..ca82763
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S
@@ -0,0 +1,101 @@
+/* MIPS3 addmul_1 -- Multiply a limb vector with a single limb and
+ * add the product to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_addmul_1
+ .ent _gcry_mpih_addmul_1
+_gcry_mpih_addmul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$3,$2 # carry from previous addition -> $2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_addmul_1
+
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S
new file mode 100644
index 0000000..be421a6
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S
@@ -0,0 +1,101 @@
+/* MIPS3 submul_1 -- Multiply a limb vector with a single limb and
+ * subtract the product from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_submul_1
+ .ent _gcry_mpih_submul_1
+_gcry_mpih_submul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$3,$2 # carry from previous addition -> $2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_submul_1
+
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S
new file mode 100644
index 0000000..e7e035a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S
@@ -0,0 +1,95 @@
+/* mips3 rshift
+ *
+ * Copyright (C) 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, ($4)
+ * mpi_ptr_t up, ($5)
+ * mpi_size_t usize, ($6)
+ * unsigned cnt) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_rshift
+ .ent _gcry_mpih_rshift
+_gcry_mpih_rshift:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5) # load first limb
+ dsubu $13,$0,$7
+ daddiu $6,$6,-1
+ and $9,$6,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ dsll $2,$10,$13 # compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,8($5)
+ daddiu $4,$4,8
+ daddiu $5,$5,8
+ daddiu $9,$9,-1
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,-8($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,8($5)
+ daddiu $4,$4,32
+ daddiu $6,$6,-4
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+
+ ld $10,16($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-32($4)
+ dsll $9,$10,$13
+
+ ld $3,24($5)
+ dsrl $11,$10,$7
+ or $8,$14,$9
+ sd $8,-24($4)
+ dsll $12,$3,$13
+
+ ld $10,32($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-16($4)
+ dsll $9,$10,$13
+
+ daddiu $5,$5,32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,-8($4)
+
+.Lend: dsrl $8,$10,$7
+ j $31
+ sd $8,0($4)
+ .end _gcry_mpih_rshift
+
diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S
new file mode 100644
index 0000000..9fac674
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S
@@ -0,0 +1,125 @@
+/* mips3 sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ *
+ * Copyright (C) 1995, 1998, 1999, 2000,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_ptr_t s2_ptr, (r6)
+ * mpi_size_t size) (r7)
+ */
+
+
+ .text
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .ent _gcry_mpih_sub_n
+_gcry_mpih_sub_n:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$2
+ ld $11,16($6)
+ sltu $8,$13,$2
+ dsubu $13,$12,$13
+ sltu $2,$12,$13
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$2
+ ld $13,24($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$2
+ ld $11,32($6)
+ sltu $8,$13,$2
+ dsubu $13,$12,$13
+ sltu $2,$12,$13
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+
+ .end _gcry_mpih_sub_n
+
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-add.c b/grub-core/lib/libgcrypt/mpi/mpi-add.c
new file mode 100644
index 0000000..98abc56
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-add.c
@@ -0,0 +1,235 @@
+/* mpi-add.c - MPI functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+
+
+/****************
+ * Add the unsigned integer V to the mpi-integer U and store the
+ * result in W. U and V may be the same.
+ */
+void
+gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize, wsize;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+ wsign = 0;
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = usize + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->d;
+ wp = w->d;
+
+ if( !usize ) { /* simple */
+ wp[0] = v;
+ wsize = v? 1:0;
+ }
+ else if( !usign ) { /* mpi is not negative */
+ mpi_limb_t cy;
+ cy = _gcry_mpih_add_1(wp, up, usize, v);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ }
+ else { /* The signs are different. Need exact comparison to determine
+ * which operand to subtract from which. */
+ if( usize == 1 && up[0] < v ) {
+ wp[0] = v - up[0];
+ wsize = 1;
+ }
+ else {
+ _gcry_mpih_sub_1(wp, up, usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = usize - (wp[usize-1]==0);
+ wsign = 1;
+ }
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+void
+gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t usize, vsize, wsize;
+ int usign, vsign, wsign;
+
+ if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
+ usize = v->nlimbs;
+ usign = v->sign;
+ vsize = u->nlimbs;
+ vsign = u->sign;
+ wsize = usize + 1;
+ RESIZE_IF_NEEDED(w, wsize);
+ /* These must be after realloc (u or v may be the same as w). */
+ up = v->d;
+ vp = u->d;
+ }
+ else {
+ usize = u->nlimbs;
+ usign = u->sign;
+ vsize = v->nlimbs;
+ vsign = v->sign;
+ wsize = usize + 1;
+ RESIZE_IF_NEEDED(w, wsize);
+ /* These must be after realloc (u or v may be the same as w). */
+ up = u->d;
+ vp = v->d;
+ }
+ wp = w->d;
+ wsign = 0;
+
+ if( !vsize ) { /* simple */
+ MPN_COPY(wp, up, usize );
+ wsize = usize;
+ wsign = usign;
+ }
+ else if( usign != vsign ) { /* different sign */
+ /* This test is right since USIZE >= VSIZE */
+ if( usize != vsize ) {
+ _gcry_mpih_sub(wp, up, usize, vp, vsize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ wsign = usign;
+ }
+ else if( _gcry_mpih_cmp(up, vp, usize) < 0 ) {
+ _gcry_mpih_sub_n(wp, vp, up, usize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ if( !usign )
+ wsign = 1;
+ }
+ else {
+ _gcry_mpih_sub_n(wp, up, vp, usize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ if( usign )
+ wsign = 1;
+ }
+ }
+ else { /* U and V have same sign. Add them. */
+ mpi_limb_t cy = _gcry_mpih_add(wp, up, usize, vp, vsize);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ if( usign )
+ wsign = 1;
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+/****************
+ * Subtract the unsigned integer V from the mpi-integer U and store the
+ * result in W.
+ */
+void
+gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize, wsize;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+ wsign = 0;
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = usize + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->d;
+ wp = w->d;
+
+ if( !usize ) { /* simple */
+ wp[0] = v;
+ wsize = v? 1:0;
+ wsign = 1;
+ }
+ else if( usign ) { /* mpi and v are negative */
+ mpi_limb_t cy;
+ cy = _gcry_mpih_add_1(wp, up, usize, v);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ }
+ else { /* The signs are different. Need exact comparison to determine
+ * which operand to subtract from which. */
+ if( usize == 1 && up[0] < v ) {
+ wp[0] = v - up[0];
+ wsize = 1;
+ wsign = 1;
+ }
+ else {
+ _gcry_mpih_sub_1(wp, up, usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = usize - (wp[usize-1]==0);
+ }
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+void
+gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ gcry_mpi_t vv = mpi_copy (v);
+ vv->sign = ! vv->sign;
+ gcry_mpi_add (w, u, vv);
+ mpi_free (vv);
+}
+
+
+void
+gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ gcry_mpi_add(w, u, v);
+ _gcry_mpi_fdiv_r( w, w, m );
+}
+
+void
+gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ gcry_mpi_sub(w, u, v);
+ _gcry_mpi_fdiv_r( w, w, m );
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-bit.c b/grub-core/lib/libgcrypt/mpi/mpi-bit.c
new file mode 100644
index 0000000..cdc6b0b
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-bit.c
@@ -0,0 +1,364 @@
+/* mpi-bit.c - MPI bit level functions
+ * Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+#ifdef MPI_INTERNAL_NEED_CLZ_TAB
+#ifdef __STDC__
+const
+#endif
+unsigned char
+_gcry_clz_tab[] =
+{
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+#endif
+
+
+#define A_LIMB_1 ((mpi_limb_t)1)
+
+
+/****************
+ * Sometimes we have MSL (most significant limbs) which are 0;
+ * this is for some reasons not good, so this function removes them.
+ */
+void
+_gcry_mpi_normalize( gcry_mpi_t a )
+{
+ if( mpi_is_opaque(a) )
+ return;
+
+ for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
+ ;
+}
+
+
+
+/****************
+ * Return the number of bits in A.
+ */
+unsigned int
+gcry_mpi_get_nbits( gcry_mpi_t a )
+{
+ unsigned n;
+
+ if( mpi_is_opaque(a) ) {
+ return a->sign; /* which holds the number of bits */
+ }
+
+ _gcry_mpi_normalize( a );
+ if( a->nlimbs ) {
+ mpi_limb_t alimb = a->d[a->nlimbs-1];
+ if( alimb )
+ count_leading_zeros( n, alimb );
+ else
+ n = BITS_PER_MPI_LIMB;
+ n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
+ }
+ else
+ n = 0;
+ return n;
+}
+
+
+/****************
+ * Test whether bit N is set.
+ */
+int
+gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+ mpi_limb_t limb;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return 0; /* too far left: this is a 0 */
+ limb = a->d[limbno];
+ return (limb & (A_LIMB_1 << bitno))? 1: 0;
+}
+
+
+/****************
+ * Set bit N of A.
+ */
+void
+gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if ( limbno >= a->nlimbs )
+ {
+ mpi_resize (a, limbno+1 );
+ a->nlimbs = limbno+1;
+ }
+ a->d[limbno] |= (A_LIMB_1<<bitno);
+}
+
+/****************
+ * Set bit N of A. and clear all bits above
+ */
+void
+gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if ( limbno >= a->nlimbs )
+ {
+ mpi_resize (a, limbno+1 );
+ a->nlimbs = limbno+1;
+ }
+ a->d[limbno] |= (A_LIMB_1<<bitno);
+ for ( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
+}
+
+/****************
+ * clear bit N of A and all bits above
+ */
+void
+gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return; /* not allocated, therefore no need to clear bits
+ :-) */
+
+ for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
+}
+
+/****************
+ * Clear bit N of A.
+ */
+void
+gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return; /* don't need to clear this bit, it's to far to left */
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+}
+
+
+/****************
+ * Shift A by COUNT limbs to the right
+ * This is used only within the MPI library
+ */
+void
+_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
+{
+ mpi_ptr_t ap = a->d;
+ mpi_size_t n = a->nlimbs;
+ unsigned int i;
+
+ if( count >= n ) {
+ a->nlimbs = 0;
+ return;
+ }
+
+ for( i = 0; i < n - count; i++ )
+ ap[i] = ap[i+count];
+ ap[i] = 0;
+ a->nlimbs -= count;
+}
+
+
+/*
+ * Shift A by N bits to the right.
+ */
+void
+gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+{
+ mpi_size_t xsize;
+ unsigned int i;
+ unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
+ unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+
+ if ( x == a )
+ {
+ /* In-place operation. */
+ if ( nlimbs >= x->nlimbs )
+ {
+ x->nlimbs = 0;
+ return;
+ }
+
+ if (nlimbs)
+ {
+ for (i=0; i < x->nlimbs - nlimbs; i++ )
+ x->d[i] = x->d[i+nlimbs];
+ x->d[i] = 0;
+ x->nlimbs -= nlimbs;
+
+ }
+ if ( x->nlimbs && nbits )
+ _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits );
+ }
+ else if ( nlimbs )
+ {
+ /* Copy and shift by more or equal bits than in a limb. */
+ xsize = a->nlimbs;
+ x->sign = a->sign;
+ RESIZE_IF_NEEDED (x, xsize);
+ x->nlimbs = xsize;
+ for (i=0; i < a->nlimbs; i++ )
+ x->d[i] = a->d[i];
+ x->nlimbs = i;
+
+ if ( nlimbs >= x->nlimbs )
+ {
+ x->nlimbs = 0;
+ return;
+ }
+
+ if (nlimbs)
+ {
+ for (i=0; i < x->nlimbs - nlimbs; i++ )
+ x->d[i] = x->d[i+nlimbs];
+ x->d[i] = 0;
+ x->nlimbs -= nlimbs;
+ }
+
+ if ( x->nlimbs && nbits )
+ _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits );
+ }
+ else
+ {
+ /* Copy and shift by less than bits in a limb. */
+ xsize = a->nlimbs;
+ x->sign = a->sign;
+ RESIZE_IF_NEEDED (x, xsize);
+ x->nlimbs = xsize;
+
+ if ( xsize )
+ {
+ if (nbits )
+ _gcry_mpih_rshift (x->d, a->d, x->nlimbs, nbits );
+ else
+ {
+ /* The rshift helper function is not specified for
+ NBITS==0, thus we do a plain copy here. */
+ for (i=0; i < x->nlimbs; i++ )
+ x->d[i] = a->d[i];
+ }
+ }
+ }
+ MPN_NORMALIZE (x->d, x->nlimbs);
+}
+
+
+/****************
+ * Shift A by COUNT limbs to the left
+ * This is used only within the MPI library
+ */
+void
+_gcry_mpi_lshift_limbs (gcry_mpi_t a, unsigned int count)
+{
+ mpi_ptr_t ap;
+ int n = a->nlimbs;
+ int i;
+
+ if (!count || !n)
+ return;
+
+ RESIZE_IF_NEEDED (a, n+count);
+
+ ap = a->d;
+ for (i = n-1; i >= 0; i--)
+ ap[i+count] = ap[i];
+ for (i=0; i < count; i++ )
+ ap[i] = 0;
+ a->nlimbs += count;
+}
+
+
+/*
+ * Shift A by N bits to the left.
+ */
+void
+gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+{
+ unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
+ unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+
+ if (x == a && !n)
+ return; /* In-place shift with an amount of zero. */
+
+ if ( x != a )
+ {
+ /* Copy A to X. */
+ unsigned int alimbs = a->nlimbs;
+ int asign = a->sign;
+ mpi_ptr_t xp, ap;
+
+ RESIZE_IF_NEEDED (x, alimbs+nlimbs+1);
+ xp = x->d;
+ ap = a->d;
+ MPN_COPY (xp, ap, alimbs);
+ x->nlimbs = alimbs;
+ x->flags = a->flags;
+ x->sign = asign;
+ }
+
+ if (nlimbs && !nbits)
+ {
+ /* Shift a full number of limbs. */
+ _gcry_mpi_lshift_limbs (x, nlimbs);
+ }
+ else if (n)
+ {
+ /* We use a very dump approach: Shift left by the number of
+ limbs plus one and than fix it up by an rshift. */
+ _gcry_mpi_lshift_limbs (x, nlimbs+1);
+ gcry_mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits);
+ }
+
+ MPN_NORMALIZE (x->d, x->nlimbs);
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-cmp.c b/grub-core/lib/libgcrypt/mpi/mpi-cmp.c
new file mode 100644
index 0000000..30e1fce
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-cmp.c
@@ -0,0 +1,107 @@
+/* mpi-cmp.c - MPI functions
+ * Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+int
+gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
+{
+ mpi_limb_t limb = v;
+
+ _gcry_mpi_normalize (u);
+
+ /* Handle the case that U contains no limb. */
+ if (u->nlimbs == 0)
+ return -(limb != 0);
+
+ /* Handle the case that U is negative. */
+ if (u->sign)
+ return -1;
+
+ if (u->nlimbs == 1)
+ {
+ /* Handle the case that U contains exactly one limb. */
+
+ if (u->d[0] > limb)
+ return 1;
+ if (u->d[0] < limb)
+ return -1;
+ return 0;
+ }
+ else
+ /* Handle the case that U contains more than one limb. */
+ return 1;
+}
+
+
+int
+gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
+{
+ mpi_size_t usize;
+ mpi_size_t vsize;
+ int cmp;
+
+ if (mpi_is_opaque (u) || mpi_is_opaque (v))
+ {
+ if (mpi_is_opaque (u) && !mpi_is_opaque (v))
+ return -1;
+ if (!mpi_is_opaque (u) && mpi_is_opaque (v))
+ return 1;
+ if (!u->sign && !v->sign)
+ return 0; /* Empty buffers are identical. */
+ if (u->sign < v->sign)
+ return -1;
+ if (u->sign > v->sign)
+ return 1;
+ return memcmp (u->d, v->d, (u->sign+7)/8);
+ }
+ else
+ {
+ _gcry_mpi_normalize (u);
+ _gcry_mpi_normalize (v);
+
+ usize = u->nlimbs;
+ vsize = v->nlimbs;
+
+ /* Compare sign bits. */
+
+ if (!u->sign && v->sign)
+ return 1;
+ if (u->sign && !v->sign)
+ return -1;
+
+ /* U and V are either both positive or both negative. */
+
+ if (usize != vsize && !u->sign && !v->sign)
+ return usize - vsize;
+ if (usize != vsize && u->sign && v->sign)
+ return vsize + usize;
+ if (!usize )
+ return 0;
+ if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize)))
+ return 0;
+ if ((cmp < 0?1:0) == (u->sign?1:0))
+ return 1;
+ }
+ return -1;
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-div.c b/grub-core/lib/libgcrypt/mpi/mpi-div.c
new file mode 100644
index 0000000..a6ee300
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-div.c
@@ -0,0 +1,355 @@
+/* mpi-div.c - MPI functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+void
+_gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ int divisor_sign = divisor->sign;
+ gcry_mpi_t temp_divisor = NULL;
+
+ /* We need the original value of the divisor after the remainder has been
+ * preliminary calculated. We have to copy it to temporary space if it's
+ * the same variable as REM. */
+ if( rem == divisor ) {
+ temp_divisor = mpi_copy( divisor );
+ divisor = temp_divisor;
+ }
+
+ _gcry_mpi_tdiv_r( rem, dividend, divisor );
+
+ if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
+ gcry_mpi_add( rem, rem, divisor);
+
+ if( temp_divisor )
+ mpi_free(temp_divisor);
+}
+
+
+
+/****************
+ * Division rounding the quotient towards -infinity.
+ * The remainder gets the same sign as the denominator.
+ * rem is optional
+ */
+
+ulong
+_gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor )
+{
+ mpi_limb_t rlimb;
+
+ rlimb = _gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor );
+ if( rlimb && dividend->sign )
+ rlimb = divisor - rlimb;
+
+ if( rem ) {
+ rem->d[0] = rlimb;
+ rem->nlimbs = rlimb? 1:0;
+ }
+ return rlimb;
+}
+
+
+void
+_gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ gcry_mpi_t tmp = mpi_alloc( mpi_get_nlimbs(quot) );
+ _gcry_mpi_fdiv_qr( quot, tmp, dividend, divisor);
+ mpi_free(tmp);
+}
+
+void
+_gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ int divisor_sign = divisor->sign;
+ gcry_mpi_t temp_divisor = NULL;
+
+ if( quot == divisor || rem == divisor ) {
+ temp_divisor = mpi_copy( divisor );
+ divisor = temp_divisor;
+ }
+
+ _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor );
+
+ if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
+ gcry_mpi_sub_ui( quot, quot, 1 );
+ gcry_mpi_add( rem, rem, divisor);
+ }
+
+ if( temp_divisor )
+ mpi_free(temp_divisor);
+}
+
+
+/* If den == quot, den needs temporary storage.
+ * If den == rem, den needs temporary storage.
+ * If num == quot, num needs temporary storage.
+ * If den has temporary storage, it can be normalized while being copied,
+ * i.e no extra storage should be allocated.
+ */
+
+void
+_gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den)
+{
+ _gcry_mpi_tdiv_qr(NULL, rem, num, den );
+}
+
+void
+_gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den)
+{
+ mpi_ptr_t np, dp;
+ mpi_ptr_t qp, rp;
+ mpi_size_t nsize = num->nlimbs;
+ mpi_size_t dsize = den->nlimbs;
+ mpi_size_t qsize, rsize;
+ mpi_size_t sign_remainder = num->sign;
+ mpi_size_t sign_quotient = num->sign ^ den->sign;
+ unsigned normalization_steps;
+ mpi_limb_t q_limb;
+ mpi_ptr_t marker[5];
+ unsigned int marker_nlimbs[5];
+ int markidx=0;
+
+ /* Ensure space is enough for quotient and remainder.
+ * We need space for an extra limb in the remainder, because it's
+ * up-shifted (normalized) below. */
+ rsize = nsize + 1;
+ mpi_resize( rem, rsize);
+
+ qsize = rsize - dsize; /* qsize cannot be bigger than this. */
+ if( qsize <= 0 ) {
+ if( num != rem ) {
+ rem->nlimbs = num->nlimbs;
+ rem->sign = num->sign;
+ MPN_COPY(rem->d, num->d, nsize);
+ }
+ if( quot ) {
+ /* This needs to follow the assignment to rem, in case the
+ * numerator and quotient are the same. */
+ quot->nlimbs = 0;
+ quot->sign = 0;
+ }
+ return;
+ }
+
+ if( quot )
+ mpi_resize( quot, qsize);
+
+ /* Read pointers here, when reallocation is finished. */
+ np = num->d;
+ dp = den->d;
+ rp = rem->d;
+
+ /* Optimize division by a single-limb divisor. */
+ if( dsize == 1 ) {
+ mpi_limb_t rlimb;
+ if( quot ) {
+ qp = quot->d;
+ rlimb = _gcry_mpih_divmod_1( qp, np, nsize, dp[0] );
+ qsize -= qp[qsize - 1] == 0;
+ quot->nlimbs = qsize;
+ quot->sign = sign_quotient;
+ }
+ else
+ rlimb = _gcry_mpih_mod_1( np, nsize, dp[0] );
+ rp[0] = rlimb;
+ rsize = rlimb != 0?1:0;
+ rem->nlimbs = rsize;
+ rem->sign = sign_remainder;
+ return;
+ }
+
+
+ if( quot ) {
+ qp = quot->d;
+ /* Make sure QP and NP point to different objects. Otherwise the
+ * numerator would be gradually overwritten by the quotient limbs. */
+ if(qp == np) { /* Copy NP object to temporary space. */
+ marker_nlimbs[markidx] = nsize;
+ np = marker[markidx++] = mpi_alloc_limb_space(nsize,
+ mpi_is_secure(quot));
+ MPN_COPY(np, qp, nsize);
+ }
+ }
+ else /* Put quotient at top of remainder. */
+ qp = rp + dsize;
+
+ count_leading_zeros( normalization_steps, dp[dsize - 1] );
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ * shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ * numerator the same number of steps (to keep the quotient the same!).
+ */
+ if( normalization_steps ) {
+ mpi_ptr_t tp;
+ mpi_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ * the most significant word. Use temporary storage not to clobber
+ * the original contents of the denominator. */
+ marker_nlimbs[markidx] = dsize;
+ tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den));
+ _gcry_mpih_lshift( tp, dp, dsize, normalization_steps );
+ dp = tp;
+
+ /* Shift up the numerator, possibly introducing a new most
+ * significant word. Move the shifted numerator in the remainder
+ * meanwhile. */
+ nlimb = _gcry_mpih_lshift(rp, np, nsize, normalization_steps);
+ if( nlimb ) {
+ rp[nsize] = nlimb;
+ rsize = nsize + 1;
+ }
+ else
+ rsize = nsize;
+ }
+ else {
+ /* The denominator is already normalized, as required. Copy it to
+ * temporary space if it overlaps with the quotient or remainder. */
+ if( dp == rp || (quot && (dp == qp))) {
+ mpi_ptr_t tp;
+
+ marker_nlimbs[markidx] = dsize;
+ tp = marker[markidx++] = mpi_alloc_limb_space(dsize,
+ mpi_is_secure(den));
+ MPN_COPY( tp, dp, dsize );
+ dp = tp;
+ }
+
+ /* Move the numerator to the remainder. */
+ if( rp != np )
+ MPN_COPY(rp, np, nsize);
+
+ rsize = nsize;
+ }
+
+ q_limb = _gcry_mpih_divrem( qp, 0, rp, rsize, dp, dsize );
+
+ if( quot ) {
+ qsize = rsize - dsize;
+ if(q_limb) {
+ qp[qsize] = q_limb;
+ qsize += 1;
+ }
+
+ quot->nlimbs = qsize;
+ quot->sign = sign_quotient;
+ }
+
+ rsize = dsize;
+ MPN_NORMALIZE (rp, rsize);
+
+ if( normalization_steps && rsize ) {
+ _gcry_mpih_rshift(rp, rp, rsize, normalization_steps);
+ rsize -= rp[rsize - 1] == 0?1:0;
+ }
+
+ rem->nlimbs = rsize;
+ rem->sign = sign_remainder;
+ while( markidx )
+ {
+ markidx--;
+ _gcry_mpi_free_limb_space (marker[markidx], marker_nlimbs[markidx]);
+ }
+}
+
+void
+_gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned int count )
+{
+ mpi_size_t usize, wsize;
+ mpi_size_t limb_cnt;
+
+ usize = u->nlimbs;
+ limb_cnt = count / BITS_PER_MPI_LIMB;
+ wsize = usize - limb_cnt;
+ if( limb_cnt >= usize )
+ w->nlimbs = 0;
+ else {
+ mpi_ptr_t wp;
+ mpi_ptr_t up;
+
+ RESIZE_IF_NEEDED( w, wsize );
+ wp = w->d;
+ up = u->d;
+
+ count %= BITS_PER_MPI_LIMB;
+ if( count ) {
+ _gcry_mpih_rshift( wp, up + limb_cnt, wsize, count );
+ wsize -= !wp[wsize - 1];
+ }
+ else {
+ MPN_COPY_INCR( wp, up + limb_cnt, wsize);
+ }
+
+ w->nlimbs = wsize;
+ }
+}
+
+/****************
+ * Check whether dividend is divisible by divisor
+ * (note: divisor must fit into a limb)
+ */
+int
+_gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor )
+{
+ return !_gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor );
+}
+
+
+void
+gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
+{
+ if (!round)
+ {
+ if (!rem)
+ {
+ gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs(quot));
+ _gcry_mpi_tdiv_qr (quot, tmp, dividend, divisor);
+ mpi_free (tmp);
+ }
+ else
+ _gcry_mpi_tdiv_qr (quot, rem, dividend, divisor);
+ }
+ else if (round < 0)
+ {
+ if (!rem)
+ _gcry_mpi_fdiv_q (quot, dividend, divisor);
+ else if (!quot)
+ _gcry_mpi_fdiv_r (rem, dividend, divisor);
+ else
+ _gcry_mpi_fdiv_qr (quot, rem, dividend, divisor);
+ }
+ else
+ log_bug ("mpi rounding to ceiling not yet implemented\n");
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-gcd.c b/grub-core/lib/libgcrypt/mpi/mpi-gcd.c
new file mode 100644
index 0000000..5cbefa1
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-gcd.c
@@ -0,0 +1,51 @@
+/* mpi-gcd.c - MPI functions
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+/****************
+ * Find the greatest common divisor G of A and B.
+ * Return: true if this 1, false in all other cases
+ */
+int
+gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb )
+{
+ gcry_mpi_t a, b;
+
+ a = mpi_copy(xa);
+ b = mpi_copy(xb);
+
+ /* TAOCP Vol II, 4.5.2, Algorithm A */
+ a->sign = 0;
+ b->sign = 0;
+ while( gcry_mpi_cmp_ui( b, 0 ) ) {
+ _gcry_mpi_fdiv_r( g, a, b ); /* g used as temorary variable */
+ mpi_set(a,b);
+ mpi_set(b,g);
+ }
+ mpi_set(g, a);
+
+ mpi_free(a);
+ mpi_free(b);
+ return !gcry_mpi_cmp_ui( g, 1);
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inline.c b/grub-core/lib/libgcrypt/mpi/mpi-inline.c
new file mode 100644
index 0000000..39e2222
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-inline.c
@@ -0,0 +1,35 @@
+/* mpi-inline.c
+ * Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* put the inline functions as real functions into the lib */
+#define G10_MPI_INLINE_DECL
+
+#include "mpi-internal.h"
+
+/* always include the header because it is only
+ * included by mpi-internal if __GCC__ is defined but we
+ * need it here in all cases and the above definition of
+ * of the macro allows us to do so
+ */
+#include "mpi-inline.h"
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inline.h b/grub-core/lib/libgcrypt/mpi/mpi-inline.h
new file mode 100644
index 0000000..88d9f56
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-inline.h
@@ -0,0 +1,154 @@
+/* mpi-inline.h - Internal to the Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_INLINE_H
+#define G10_MPI_INLINE_H
+
+#ifndef G10_MPI_INLINE_DECL
+#define G10_MPI_INLINE_DECL extern __inline__
+#endif
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb += x;
+ *res_ptr++ = s2_limb;
+ if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
+ while( --s1_size ) {
+ x = *s1_ptr++ + 1; /* add carry */
+ *res_ptr++ = x; /* and store */
+ if( x ) /* not 0 (no overflow): we can stop */
+ goto leave;
+ }
+ return 1; /* return carry (size of s1 to small) */
+ }
+
+ leave:
+ if( res_ptr != s1_ptr ) { /* not the same variable */
+ mpi_size_t i; /* copy the rest */
+ for( i=0; i < s1_size-1; i++ )
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0; /* no carry */
+}
+
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size)
+{
+ mpi_limb_t cy = 0;
+
+ if( s2_size )
+ cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
+
+ if( s1_size - s2_size )
+ cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size,
+ s1_size - s2_size, cy);
+ return cy;
+}
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb )
+{
+ mpi_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb = x - s2_limb;
+ *res_ptr++ = s2_limb;
+ if( s2_limb > x ) {
+ while( --s1_size ) {
+ x = *s1_ptr++;
+ *res_ptr++ = x - 1;
+ if( x )
+ goto leave;
+ }
+ return 1;
+ }
+
+ leave:
+ if( res_ptr != s1_ptr ) {
+ mpi_size_t i;
+ for( i=0; i < s1_size-1; i++ )
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0;
+}
+
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size)
+{
+ mpi_limb_t cy = 0;
+
+ if( s2_size )
+ cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
+
+ if( s1_size - s2_size )
+ cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
+ s1_size - s2_size, cy);
+ return cy;
+}
+
+/****************
+ * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
+ * There are no restrictions on the relative sizes of
+ * the two arguments.
+ * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.
+ */
+G10_MPI_INLINE_DECL int
+_gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size )
+{
+ mpi_size_t i;
+ mpi_limb_t op1_word, op2_word;
+
+ for( i = size - 1; i >= 0 ; i--) {
+ op1_word = op1_ptr[i];
+ op2_word = op2_ptr[i];
+ if( op1_word != op2_word )
+ goto diff;
+ }
+ return 0;
+
+ diff:
+ /* This can *not* be simplified to
+ * op2_word - op2_word
+ * since that expression might give signed overflow. */
+ return (op1_word > op2_word) ? 1 : -1;
+}
+
+
+#endif /*G10_MPI_INLINE_H*/
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-internal.h b/grub-core/lib/libgcrypt/mpi/mpi-internal.h
new file mode 100644
index 0000000..e75b7c6
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-internal.h
@@ -0,0 +1,277 @@
+/* mpi-internal.h - Internal to the Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 2000, 2002,
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_INTERNAL_H
+#define G10_MPI_INTERNAL_H
+
+#include "mpi-asm-defs.h"
+
+#ifndef BITS_PER_MPI_LIMB
+#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
+ typedef unsigned int mpi_limb_t;
+ typedef signed int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
+ typedef unsigned long int mpi_limb_t;
+ typedef signed long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
+ typedef unsigned long long int mpi_limb_t;
+ typedef signed long long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
+ typedef unsigned short int mpi_limb_t;
+ typedef signed short int mpi_limb_signed_t;
+#else
+#error BYTES_PER_MPI_LIMB does not match any C type
+#endif
+#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
+#endif /*BITS_PER_MPI_LIMB*/
+
+#include "mpi.h"
+
+/* If KARATSUBA_THRESHOLD is not already defined, define it to a
+ * value which is good on most machines. */
+
+/* tested 4, 16, 32 and 64, where 16 gave the best performance when
+ * checking a 768 and a 1024 bit ElGamal signature.
+ * (wk 22.12.97) */
+#ifndef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 16
+#endif
+
+/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
+#if KARATSUBA_THRESHOLD < 2
+#undef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 2
+#endif
+
+
+typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */
+typedef int mpi_size_t; /* (must be a signed type) */
+
+#define ABS(x) (x >= 0 ? x : -x)
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+#define RESIZE_IF_NEEDED(a,b) \
+ do { \
+ if( (a)->alloced < (b) ) \
+ mpi_resize((a), (b)); \
+ } while(0)
+
+/* Copy N limbs from S to D. */
+#define MPN_COPY( d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = (s)[_i]; \
+ } while(0)
+
+#define MPN_COPY_INCR( d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = (d)[_i]; \
+ } while (0)
+
+#define MPN_COPY_DECR( d, s, n ) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = (n)-1; _i >= 0; _i--) \
+ (d)[_i] = (s)[_i]; \
+ } while(0)
+
+/* Zero N limbs at D */
+#define MPN_ZERO(d, n) \
+ do { \
+ int _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = 0; \
+ } while (0)
+
+#define MPN_NORMALIZE(d, n) \
+ do { \
+ while( (n) > 0 ) { \
+ if( (d)[(n)-1] ) \
+ break; \
+ (n)--; \
+ } \
+ } while(0)
+
+#define MPN_NORMALIZE_NOT_ZERO(d, n) \
+ do { \
+ for(;;) { \
+ if( (d)[(n)-1] ) \
+ break; \
+ (n)--; \
+ } \
+ } while(0)
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if( (size) < KARATSUBA_THRESHOLD ) \
+ mul_n_basecase (prodp, up, vp, size); \
+ else \
+ mul_n (prodp, up, vp, size, tspace); \
+ } while (0);
+
+
+/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
+ * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
+ * If this would yield overflow, DI should be the largest possible number
+ * (i.e., only ones). For correct operation, the most significant bit of D
+ * has to be set. Put the quotient in Q and the remainder in R.
+ */
+#define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
+ do { \
+ mpi_limb_t _q, _ql, _r; \
+ mpi_limb_t _xh, _xl; \
+ umul_ppmm (_q, _ql, (nh), (di)); \
+ _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \
+ umul_ppmm (_xh, _xl, _q, (d)); \
+ sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
+ if( _xh ) { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q++; \
+ if( _xh) { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q++; \
+ } \
+ } \
+ if( _r >= (d) ) { \
+ _r -= (d); \
+ _q++; \
+ } \
+ (r) = _r; \
+ (q) = _q; \
+ } while (0)
+
+
+/*-- mpiutil.c --*/
+#define mpi_alloc_limb_space(n,f) _gcry_mpi_alloc_limb_space((n),(f))
+mpi_ptr_t _gcry_mpi_alloc_limb_space( unsigned nlimbs, int sec );
+void _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs );
+void _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned nlimbs );
+
+/*-- mpi-bit.c --*/
+#define mpi_rshift_limbs(a,n) _gcry_mpi_rshift_limbs ((a), (n))
+#define mpi_lshift_limbs(a,n) _gcry_mpi_lshift_limbs ((a), (n))
+
+void _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count );
+void _gcry_mpi_lshift_limbs( gcry_mpi_t a, unsigned int count );
+
+
+/*-- mpih-add.c --*/
+mpi_limb_t _gcry_mpih_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb );
+mpi_limb_t _gcry_mpih_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size);
+mpi_limb_t _gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size);
+
+/*-- mpih-sub.c --*/
+mpi_limb_t _gcry_mpih_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb );
+mpi_limb_t _gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size);
+mpi_limb_t _gcry_mpih_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size);
+
+/*-- mpih-cmp.c --*/
+int _gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size );
+
+/*-- mpih-mul.c --*/
+
+struct karatsuba_ctx {
+ struct karatsuba_ctx *next;
+ mpi_ptr_t tspace;
+ unsigned int tspace_nlimbs;
+ mpi_size_t tspace_size;
+ mpi_ptr_t tp;
+ unsigned int tp_nlimbs;
+ mpi_size_t tp_size;
+};
+
+void _gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx );
+
+mpi_limb_t _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+mpi_limb_t _gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+void _gcry_mpih_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t size);
+mpi_limb_t _gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize);
+void _gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size );
+void _gcry_mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
+ mpi_ptr_t tspace);
+
+void _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize,
+ struct karatsuba_ctx *ctx );
+
+
+/*-- mpih-mul_1.c (or xxx/cpu/ *.S) --*/
+mpi_limb_t _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+
+/*-- mpih-div.c --*/
+mpi_limb_t _gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb);
+mpi_limb_t _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
+ mpi_ptr_t np, mpi_size_t nsize,
+ mpi_ptr_t dp, mpi_size_t dsize);
+mpi_limb_t _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
+ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb);
+
+/*-- mpih-shift.c --*/
+mpi_limb_t _gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned cnt);
+mpi_limb_t _gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned cnt);
+
+
+/* Define stuff for longlong.h. */
+#define W_TYPE_SIZE BITS_PER_MPI_LIMB
+ typedef mpi_limb_t UWtype;
+ typedef unsigned int UHWtype;
+#if defined (__GNUC__)
+ typedef unsigned int UQItype __attribute__ ((mode (QI)));
+ typedef int SItype __attribute__ ((mode (SI)));
+ typedef unsigned int USItype __attribute__ ((mode (SI)));
+ typedef int DItype __attribute__ ((mode (DI)));
+ typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#else
+ typedef unsigned char UQItype;
+ typedef long SItype;
+ typedef unsigned long USItype;
+#endif
+
+#ifdef __GNUC__
+#include "mpi-inline.h"
+#endif
+
+#endif /*G10_MPI_INTERNAL_H*/
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inv.c b/grub-core/lib/libgcrypt/mpi/mpi-inv.c
new file mode 100644
index 0000000..5d26946
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-inv.c
@@ -0,0 +1,267 @@
+/* mpi-inv.c - MPI functions
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "g10lib.h"
+
+/****************
+ * Calculate the multiplicative inverse X of A mod N
+ * That is: Find the solution x for
+ * 1 = (a*x) mod n
+ */
+int
+gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n )
+{
+#if 0
+ gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3;
+ gcry_mpi_t ta, tb, tc;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+ u1 = mpi_alloc_set_ui(1);
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_alloc_set_ui(0);
+ v2 = mpi_alloc_set_ui(1);
+ v3 = mpi_copy(v);
+ q = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t1 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t2 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t3 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ while( mpi_cmp_ui( v3, 0 ) ) {
+ mpi_fdiv_q( q, u3, v3 );
+ mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q);
+ mpi_sub(t1, u1, t1); mpi_sub(t2, u2, t2); mpi_sub(t3, u3, t3);
+ mpi_set(u1, v1); mpi_set(u2, v2); mpi_set(u3, v3);
+ mpi_set(v1, t1); mpi_set(v2, t2); mpi_set(v3, t3);
+ }
+ /* log_debug("result:\n");
+ log_mpidump("q =", q );
+ log_mpidump("u1=", u1);
+ log_mpidump("u2=", u2);
+ log_mpidump("u3=", u3);
+ log_mpidump("v1=", v1);
+ log_mpidump("v2=", v2); */
+ mpi_set(x, u1);
+
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(u3);
+ mpi_free(v1);
+ mpi_free(v2);
+ mpi_free(v3);
+ mpi_free(q);
+ mpi_free(t1);
+ mpi_free(t2);
+ mpi_free(t3);
+ mpi_free(u);
+ mpi_free(v);
+#elif 0
+ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X)
+ * modified according to Michael Penk's solution for Exercise 35 */
+
+ /* FIXME: we can simplify this in most cases (see Knuth) */
+ gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, t1, t2, t3;
+ unsigned k;
+ int sign;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+ for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
+ mpi_rshift(u, u, 1);
+ mpi_rshift(v, v, 1);
+ }
+
+
+ u1 = mpi_alloc_set_ui(1);
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_copy(v); /* !-- used as const 1 */
+ v2 = mpi_alloc( mpi_get_nlimbs(u) ); mpi_sub( v2, u1, u );
+ v3 = mpi_copy(v);
+ if( mpi_test_bit(u, 0) ) { /* u is odd */
+ t1 = mpi_alloc_set_ui(0);
+ t2 = mpi_alloc_set_ui(1); t2->sign = 1;
+ t3 = mpi_copy(v); t3->sign = !t3->sign;
+ goto Y4;
+ }
+ else {
+ t1 = mpi_alloc_set_ui(1);
+ t2 = mpi_alloc_set_ui(0);
+ t3 = mpi_copy(u);
+ }
+ do {
+ do {
+ if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t2, t2, 1);
+ mpi_rshift(t3, t3, 1);
+ Y4:
+ ;
+ } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
+
+ if( !t3->sign ) {
+ mpi_set(u1, t1);
+ mpi_set(u2, t2);
+ mpi_set(u3, t3);
+ }
+ else {
+ mpi_sub(v1, v, t1);
+ sign = u->sign; u->sign = !u->sign;
+ mpi_sub(v2, u, t2);
+ u->sign = sign;
+ sign = t3->sign; t3->sign = !t3->sign;
+ mpi_set(v3, t3);
+ t3->sign = sign;
+ }
+ mpi_sub(t1, u1, v1);
+ mpi_sub(t2, u2, v2);
+ mpi_sub(t3, u3, v3);
+ if( t1->sign ) {
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
+ /* mpi_lshift( u3, k ); */
+ mpi_set(x, u1);
+
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(u3);
+ mpi_free(v1);
+ mpi_free(v2);
+ mpi_free(v3);
+ mpi_free(t1);
+ mpi_free(t2);
+ mpi_free(t3);
+#else
+ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X)
+ * modified according to Michael Penk's solution for Exercise 35
+ * with further enhancement */
+ gcry_mpi_t u, v, u1, u2=NULL, u3, v1, v2=NULL, v3, t1, t2=NULL, t3;
+ unsigned k;
+ int sign;
+ int odd ;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+
+ for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
+ mpi_rshift(u, u, 1);
+ mpi_rshift(v, v, 1);
+ }
+ odd = mpi_test_bit(v,0);
+
+ u1 = mpi_alloc_set_ui(1);
+ if( !odd )
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_copy(v);
+ if( !odd ) {
+ v2 = mpi_alloc( mpi_get_nlimbs(u) );
+ mpi_sub( v2, u1, u ); /* U is used as const 1 */
+ }
+ v3 = mpi_copy(v);
+ if( mpi_test_bit(u, 0) ) { /* u is odd */
+ t1 = mpi_alloc_set_ui(0);
+ if( !odd ) {
+ t2 = mpi_alloc_set_ui(1); t2->sign = 1;
+ }
+ t3 = mpi_copy(v); t3->sign = !t3->sign;
+ goto Y4;
+ }
+ else {
+ t1 = mpi_alloc_set_ui(1);
+ if( !odd )
+ t2 = mpi_alloc_set_ui(0);
+ t3 = mpi_copy(u);
+ }
+ do {
+ do {
+ if( !odd ) {
+ if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t2, t2, 1);
+ mpi_rshift(t3, t3, 1);
+ }
+ else {
+ if( mpi_test_bit(t1, 0) )
+ mpi_add(t1, t1, v);
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t3, t3, 1);
+ }
+ Y4:
+ ;
+ } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
+
+ if( !t3->sign ) {
+ mpi_set(u1, t1);
+ if( !odd )
+ mpi_set(u2, t2);
+ mpi_set(u3, t3);
+ }
+ else {
+ mpi_sub(v1, v, t1);
+ sign = u->sign; u->sign = !u->sign;
+ if( !odd )
+ mpi_sub(v2, u, t2);
+ u->sign = sign;
+ sign = t3->sign; t3->sign = !t3->sign;
+ mpi_set(v3, t3);
+ t3->sign = sign;
+ }
+ mpi_sub(t1, u1, v1);
+ if( !odd )
+ mpi_sub(t2, u2, v2);
+ mpi_sub(t3, u3, v3);
+ if( t1->sign ) {
+ mpi_add(t1, t1, v);
+ if( !odd )
+ mpi_sub(t2, t2, u);
+ }
+ } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
+ /* mpi_lshift( u3, k ); */
+ mpi_set(x, u1);
+
+ mpi_free(u1);
+ mpi_free(v1);
+ mpi_free(t1);
+ if( !odd ) {
+ mpi_free(u2);
+ mpi_free(v2);
+ mpi_free(t2);
+ }
+ mpi_free(u3);
+ mpi_free(v3);
+ mpi_free(t3);
+
+ mpi_free(u);
+ mpi_free(v);
+#endif
+ return 1;
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mod.c b/grub-core/lib/libgcrypt/mpi/mpi-mod.c
new file mode 100644
index 0000000..7ebfe6d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-mod.c
@@ -0,0 +1,184 @@
+/* mpi-mod.c - Modular reduction
+ Copyright (C) 1998, 1999, 2001, 2002, 2003,
+ 2007 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+/* Context used with Barrett reduction. */
+struct barrett_ctx_s
+{
+ gcry_mpi_t m; /* The modulus - may not be modified. */
+ int m_copied; /* If true, M needs to be released. */
+ int k;
+ gcry_mpi_t y;
+ gcry_mpi_t r1; /* Helper MPI. */
+ gcry_mpi_t r2; /* Helper MPI. */
+ gcry_mpi_t r3; /* Helper MPI allocated on demand. */
+};
+
+
+
+void
+_gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor)
+{
+ _gcry_mpi_fdiv_r (rem, dividend, divisor);
+ rem->sign = 0;
+}
+
+
+/* This function returns a new context for Barrett based operations on
+ the modulus M. This context needs to be released using
+ _gcry_mpi_barrett_free. If COPY is true M will be transferred to
+ the context and the user may change M. If COPY is false, M may not
+ be changed until gcry_mpi_barrett_free has been called. */
+mpi_barrett_t
+_gcry_mpi_barrett_init (gcry_mpi_t m, int copy)
+{
+ mpi_barrett_t ctx;
+ gcry_mpi_t tmp;
+
+ mpi_normalize (m);
+ ctx = gcry_xcalloc (1, sizeof *ctx);
+
+ if (copy)
+ {
+ ctx->m = mpi_copy (m);
+ ctx->m_copied = 1;
+ }
+ else
+ ctx->m = m;
+
+ ctx->k = mpi_get_nlimbs (m);
+ tmp = mpi_alloc (ctx->k + 1);
+
+ /* Barrett precalculation: y = floor(b^(2k) / m). */
+ mpi_set_ui (tmp, 1);
+ mpi_lshift_limbs (tmp, 2 * ctx->k);
+ mpi_fdiv_q (tmp, tmp, m);
+
+ ctx->y = tmp;
+ ctx->r1 = mpi_alloc ( 2 * ctx->k + 1 );
+ ctx->r2 = mpi_alloc ( 2 * ctx->k + 1 );
+
+ return ctx;
+}
+
+void
+_gcry_mpi_barrett_free (mpi_barrett_t ctx)
+{
+ if (ctx)
+ {
+ mpi_free (ctx->y);
+ mpi_free (ctx->r1);
+ mpi_free (ctx->r2);
+ if (ctx->r3)
+ mpi_free (ctx->r3);
+ if (ctx->m_copied)
+ mpi_free (ctx->m);
+ gcry_free (ctx);
+ }
+}
+
+
+/* R = X mod M
+
+ Using Barrett reduction. Before using this function
+ _gcry_mpi_barrett_init must have been called to do the
+ precalculations. CTX is the context created by this precalculation
+ and also conveys M. If the Barret reduction could no be done a
+ starightforward reduction method is used.
+
+ We assume that these conditions are met:
+ Input: x =(x_2k-1 ...x_0)_b
+ m =(m_k-1 ....m_0)_b with m_k-1 != 0
+ Output: r = x mod m
+ */
+void
+_gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
+{
+ gcry_mpi_t m = ctx->m;
+ int k = ctx->k;
+ gcry_mpi_t y = ctx->y;
+ gcry_mpi_t r1 = ctx->r1;
+ gcry_mpi_t r2 = ctx->r2;
+
+ mpi_normalize (x);
+ if (mpi_get_nlimbs (x) > 2*k )
+ {
+ mpi_mod (r, x, m);
+ return;
+ }
+
+ /* 1. q1 = floor( x / b^k-1)
+ * q2 = q1 * y
+ * q3 = floor( q2 / b^k+1 )
+ * Actually, we don't need qx, we can work direct on r2
+ */
+ mpi_set ( r2, x );
+ mpi_rshift_limbs ( r2, k-1 );
+ mpi_mul ( r2, r2, y );
+ mpi_rshift_limbs ( r2, k+1 );
+
+ /* 2. r1 = x mod b^k+1
+ * r2 = q3 * m mod b^k+1
+ * r = r1 - r2
+ * 3. if r < 0 then r = r + b^k+1
+ */
+ mpi_set ( r1, x );
+ if ( r1->nlimbs > k+1 ) /* Quick modulo operation. */
+ r1->nlimbs = k+1;
+ mpi_mul ( r2, r2, m );
+ if ( r2->nlimbs > k+1 ) /* Quick modulo operation. */
+ r2->nlimbs = k+1;
+ mpi_sub ( r, r1, r2 );
+
+ if ( mpi_is_neg( r ) )
+ {
+ if (!ctx->r3)
+ {
+ ctx->r3 = mpi_alloc ( k + 2 );
+ mpi_set_ui (ctx->r3, 1);
+ mpi_lshift_limbs (ctx->r3, k + 1 );
+ }
+ mpi_add ( r, r, ctx->r3 );
+ }
+
+ /* 4. while r >= m do r = r - m */
+ while ( mpi_cmp( r, m ) >= 0 )
+ mpi_sub ( r, r, m );
+
+}
+
+
+void
+_gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
+ mpi_barrett_t ctx)
+{
+ gcry_mpi_mul (w, u, v);
+ mpi_mod_barrett (w, w, ctx);
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mpow.c b/grub-core/lib/libgcrypt/mpi/mpi-mpow.c
new file mode 100644
index 0000000..ca5b3f1
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-mpow.c
@@ -0,0 +1,223 @@
+/* mpi-mpow.c - MPI functions
+ * Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+/* Barrett is slower than the classical way. It can be tweaked by
+ * using partial multiplications
+ */
+/*#define USE_BARRETT*/
+
+
+
+#ifdef USE_BARRETT
+static void barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
+static gcry_mpi_t init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 );
+static int calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
+#else
+#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) gcry_mpi_mulm( (w), (u), (v), (m) )
+#endif
+
+
+static int
+build_index( gcry_mpi_t *exparray, int k, int i, int t )
+{
+ int j, bitno;
+ int idx = 0;
+
+ bitno = t-i;
+ for(j=k-1; j >= 0; j-- ) {
+ idx <<= 1;
+ if( mpi_test_bit( exparray[j], bitno ) )
+ idx |= 1;
+ }
+ /*log_debug("t=%d i=%d idx=%d\n", t, i, idx );*/
+ return idx;
+}
+
+/****************
+ * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
+ */
+void
+_gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t m)
+{
+ int k; /* number of elements */
+ int t; /* bit size of largest exponent */
+ int i, j, idx;
+ gcry_mpi_t *G; /* table with precomputed values of size 2^k */
+ gcry_mpi_t tmp;
+#ifdef USE_BARRETT
+ gcry_mpi_t barrett_y, barrett_r1, barrett_r2;
+ int barrett_k;
+#endif
+
+ for(k=0; basearray[k]; k++ )
+ ;
+ gcry_assert(k);
+ for(t=0, i=0; (tmp=exparray[i]); i++ ) {
+ /*log_mpidump("exp: ", tmp );*/
+ j = mpi_get_nbits(tmp);
+ if( j > t )
+ t = j;
+ }
+ /*log_mpidump("mod: ", m );*/
+ gcry_assert (i==k);
+ gcry_assert (t);
+ gcry_assert (k < 10);
+
+ G = gcry_xcalloc( (1<<k) , sizeof *G );
+#ifdef USE_BARRETT
+ barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
+#endif
+ /* and calculate */
+ tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
+ mpi_set_ui( res, 1 );
+ for(i = 1; i <= t; i++ ) {
+ barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
+ barrett_r1, barrett_r2 );
+ idx = build_index( exparray, k, i, t );
+ gcry_assert (idx >= 0 && idx < (1<<k));
+ if( !G[idx] ) {
+ if( !idx )
+ G[0] = mpi_alloc_set_ui( 1 );
+ else {
+ for(j=0; j < k; j++ ) {
+ if( (idx & (1<<j) ) ) {
+ if( !G[idx] )
+ G[idx] = mpi_copy( basearray[j] );
+ else
+ barrett_mulm( G[idx], G[idx], basearray[j],
+ m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
+ }
+ }
+ if( !G[idx] )
+ G[idx] = mpi_alloc(0);
+ }
+ }
+ barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
+ }
+
+ /* cleanup */
+ mpi_free(tmp);
+#ifdef USE_BARRETT
+ mpi_free(barrett_y);
+ mpi_free(barrett_r1);
+ mpi_free(barrett_r2);
+#endif
+ for(i=0; i < (1<<k); i++ )
+ mpi_free(G[i]);
+ gcry_free(G);
+}
+
+
+
+#ifdef USE_BARRETT
+static void
+barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 )
+{
+ mpi_mul(w, u, v);
+ if( calc_barrett( w, w, m, y, k, r1, r2 ) )
+ mpi_fdiv_r( w, w, m );
+}
+
+/****************
+ * Barrett precalculation: y = floor(b^(2k) / m)
+ */
+static gcry_mpi_t
+init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 )
+{
+ gcry_mpi_t tmp;
+
+ mpi_normalize( m );
+ *k = mpi_get_nlimbs( m );
+ tmp = mpi_alloc( *k + 1 );
+ mpi_set_ui( tmp, 1 );
+ mpi_lshift_limbs( tmp, 2 * *k );
+ mpi_fdiv_q( tmp, tmp, m );
+ *r1 = mpi_alloc( 2* *k + 1 );
+ *r2 = mpi_alloc( 2* *k + 1 );
+ return tmp;
+}
+
+/****************
+ * Barrett reduction: We assume that these conditions are met:
+ * Given x =(x_2k-1 ...x_0)_b
+ * m =(m_k-1 ....m_0)_b with m_k-1 != 0
+ * Output r = x mod m
+ * Before using this function init_barret must be used to calucalte y and k.
+ * Returns: false = no error
+ * true = can't perform barret reduction
+ */
+static int
+calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 )
+{
+ int xx = k > 3 ? k-3:0;
+
+ mpi_normalize( x );
+ if( mpi_get_nlimbs(x) > 2*k )
+ return 1; /* can't do it */
+
+ /* 1. q1 = floor( x / b^k-1)
+ * q2 = q1 * y
+ * q3 = floor( q2 / b^k+1 )
+ * Actually, we don't need qx, we can work direct on r2
+ */
+ mpi_set( r2, x );
+ mpi_rshift_limbs( r2, k-1 );
+ mpi_mul( r2, r2, y );
+ mpi_rshift_limbs( r2, k+1 );
+
+ /* 2. r1 = x mod b^k+1
+ * r2 = q3 * m mod b^k+1
+ * r = r1 - r2
+ * 3. if r < 0 then r = r + b^k+1
+ */
+ mpi_set( r1, x );
+ if( r1->nlimbs > k+1 ) /* quick modulo operation */
+ r1->nlimbs = k+1;
+ mpi_mul( r2, r2, m );
+ if( r2->nlimbs > k+1 ) /* quick modulo operation */
+ r2->nlimbs = k+1;
+ mpi_sub( r, r1, r2 );
+
+ if( mpi_is_neg( r ) ) {
+ gcry_mpi_t tmp;
+
+ tmp = mpi_alloc( k + 2 );
+ mpi_set_ui( tmp, 1 );
+ mpi_lshift_limbs( tmp, k+1 );
+ mpi_add( r, r, tmp );
+ mpi_free(tmp);
+ }
+
+ /* 4. while r >= m do r = r - m */
+ while( mpi_cmp( r, m ) >= 0 )
+ mpi_sub( r, r, m );
+
+ return 0;
+}
+#endif /* USE_BARRETT */
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mul.c b/grub-core/lib/libgcrypt/mpi/mpi-mul.c
new file mode 100644
index 0000000..9aefd21
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-mul.c
@@ -0,0 +1,212 @@
+/* mpi-mul.c - MPI functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+
+void
+gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult )
+{
+ mpi_size_t size, prod_size;
+ mpi_ptr_t prod_ptr;
+ mpi_limb_t cy;
+ int sign;
+
+ size = mult->nlimbs;
+ sign = mult->sign;
+
+ if( !size || !small_mult ) {
+ prod->nlimbs = 0;
+ prod->sign = 0;
+ return;
+ }
+
+ prod_size = size + 1;
+ if( prod->alloced < prod_size )
+ mpi_resize( prod, prod_size );
+ prod_ptr = prod->d;
+
+ cy = _gcry_mpih_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
+ if( cy )
+ prod_ptr[size++] = cy;
+ prod->nlimbs = size;
+ prod->sign = sign;
+}
+
+
+void
+gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
+{
+ mpi_size_t usize, wsize, limb_cnt;
+ mpi_ptr_t wp;
+ mpi_limb_t wlimb;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+
+ if( !usize ) {
+ w->nlimbs = 0;
+ w->sign = 0;
+ return;
+ }
+
+ limb_cnt = cnt / BITS_PER_MPI_LIMB;
+ wsize = usize + limb_cnt + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize );
+ wp = w->d;
+ wsize = usize + limb_cnt;
+ wsign = usign;
+
+ cnt %= BITS_PER_MPI_LIMB;
+ if( cnt ) {
+ wlimb = _gcry_mpih_lshift( wp + limb_cnt, u->d, usize, cnt );
+ if( wlimb ) {
+ wp[wsize] = wlimb;
+ wsize++;
+ }
+ }
+ else {
+ MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
+ }
+
+ /* Zero all whole limbs at low end. Do it here and not before calling
+ * mpn_lshift, not to lose for U == W. */
+ MPN_ZERO( wp, limb_cnt );
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+void
+gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ mpi_size_t usize, vsize, wsize;
+ mpi_ptr_t up, vp, wp;
+ mpi_limb_t cy;
+ int usign, vsign, usecure, vsecure, sign_product;
+ int assign_wp=0;
+ mpi_ptr_t tmp_limb=NULL;
+ unsigned int tmp_limb_nlimbs = 0;
+
+ if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
+ usize = v->nlimbs;
+ usign = v->sign;
+ usecure = mpi_is_secure(v);
+ up = v->d;
+ vsize = u->nlimbs;
+ vsign = u->sign;
+ vsecure = mpi_is_secure(u);
+ vp = u->d;
+ }
+ else {
+ usize = u->nlimbs;
+ usign = u->sign;
+ usecure = mpi_is_secure(u);
+ up = u->d;
+ vsize = v->nlimbs;
+ vsign = v->sign;
+ vsecure = mpi_is_secure(v);
+ vp = v->d;
+ }
+ sign_product = usign ^ vsign;
+ wp = w->d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
+ /* w is not allocated in secure space but u or v is. To make sure
+ * that no temporray results are stored in w, we temporary use
+ * a newly allocated limb space for w */
+ wp = mpi_alloc_limb_space( wsize, 1 );
+ assign_wp = 2; /* mark it as 2 so that we can later copy it back to
+ * mormal memory */
+ }
+ else if( w->alloced < wsize ) {
+ if( wp == up || wp == vp ) {
+ wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
+ assign_wp = 1;
+ }
+ else {
+ mpi_resize(w, wsize );
+ wp = w->d;
+ }
+ }
+ else { /* Make U and V not overlap with W. */
+ if( wp == up ) {
+ /* W and U are identical. Allocate temporary space for U. */
+ tmp_limb_nlimbs = usize;
+ up = tmp_limb = mpi_alloc_limb_space( usize, usecure );
+ /* Is V identical too? Keep it identical with U. */
+ if( wp == vp )
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY( up, wp, usize );
+ }
+ else if( wp == vp ) {
+ /* W and V are identical. Allocate temporary space for V. */
+ tmp_limb_nlimbs = vsize;
+ vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
+ /* Copy to the temporary space. */
+ MPN_COPY( vp, wp, vsize );
+ }
+ }
+
+ if( !vsize )
+ wsize = 0;
+ else {
+ cy = _gcry_mpih_mul( wp, up, usize, vp, vsize );
+ wsize -= cy? 0:1;
+ }
+
+ if( assign_wp ) {
+ if (assign_wp == 2) {
+ /* copy the temp wp from secure memory back to normal memory */
+ mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
+ MPN_COPY (tmp_wp, wp, wsize);
+ _gcry_mpi_free_limb_space (wp, 0);
+ wp = tmp_wp;
+ }
+ _gcry_mpi_assign_limb_space( w, wp, wsize );
+ }
+ w->nlimbs = wsize;
+ w->sign = sign_product;
+ if( tmp_limb )
+ _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs);
+}
+
+
+void
+gcry_mpi_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ gcry_mpi_mul(w, u, v);
+ _gcry_mpi_fdiv_r( w, w, m );
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-pow.c b/grub-core/lib/libgcrypt/mpi/mpi-pow.c
new file mode 100644
index 0000000..33bbebe
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-pow.c
@@ -0,0 +1,324 @@
+/* mpi-pow.c - MPI functions for exponentiation
+ * Copyright (C) 1994, 1996, 1998, 2000, 2002
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+/****************
+ * RES = BASE ^ EXPO mod MOD
+ */
+void
+gcry_mpi_powm (gcry_mpi_t res,
+ gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+{
+ /* Pointer to the limbs of the arguments, their size and signs. */
+ mpi_ptr_t rp, ep, mp, bp;
+ mpi_size_t esize, msize, bsize, rsize;
+ int msign, bsign, rsign;
+ /* Flags telling the secure allocation status of the arguments. */
+ int esec, msec, bsec;
+ /* Size of the result including space for temporary values. */
+ mpi_size_t size;
+ /* Helper. */
+ int mod_shift_cnt;
+ int negative_result;
+ mpi_ptr_t mp_marker = NULL;
+ mpi_ptr_t bp_marker = NULL;
+ mpi_ptr_t ep_marker = NULL;
+ mpi_ptr_t xp_marker = NULL;
+ unsigned int mp_nlimbs = 0;
+ unsigned int bp_nlimbs = 0;
+ unsigned int ep_nlimbs = 0;
+ unsigned int xp_nlimbs = 0;
+ mpi_ptr_t tspace = NULL;
+ mpi_size_t tsize = 0;
+
+
+ esize = expo->nlimbs;
+ msize = mod->nlimbs;
+ size = 2 * msize;
+ msign = mod->sign;
+
+ esec = mpi_is_secure(expo);
+ msec = mpi_is_secure(mod);
+ bsec = mpi_is_secure(base);
+
+ rp = res->d;
+ ep = expo->d;
+
+ if (!msize)
+ msize = 1 / msize; /* Provoke a signal. */
+
+ if (!esize)
+ {
+ /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
+ on if MOD equals 1. */
+ rp[0] = 1;
+ res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+ res->sign = 0;
+ goto leave;
+ }
+
+ /* Normalize MOD (i.e. make its most significant bit set) as
+ required by mpn_divrem. This will make the intermediate values
+ in the calculation slightly larger, but the correct result is
+ obtained after a final reduction using the original MOD value. */
+ mp_nlimbs = msec? msize:0;
+ mp = mp_marker = mpi_alloc_limb_space(msize, msec);
+ count_leading_zeros (mod_shift_cnt, mod->d[msize-1]);
+ if (mod_shift_cnt)
+ _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt);
+ else
+ MPN_COPY( mp, mod->d, msize );
+
+ bsize = base->nlimbs;
+ bsign = base->sign;
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it.
+
+ Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp_nlimbs = bsec ? (bsize + 1):0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
+ MPN_COPY ( bp, base->d, bsize );
+ /* We don't care about the quotient, store it above the
+ * remainder, at BP + MSIZE. */
+ _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize );
+ bsize = msize;
+ /* Canonicalize the base, since we are going to multiply with it
+ quite a few times. */
+ MPN_NORMALIZE( bp, bsize );
+ }
+ else
+ bp = base->d;
+
+ if (!bsize)
+ {
+ res->nlimbs = 0;
+ res->sign = 0;
+ goto leave;
+ }
+
+
+ /* Make BASE, EXPO and MOD not overlap with RES. */
+ if ( rp == bp )
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ gcry_assert (!bp_marker);
+ bp_nlimbs = bsec? bsize:0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
+ MPN_COPY(bp, rp, bsize);
+ }
+ if ( rp == ep )
+ {
+ /* RES and EXPO are identical. Allocate temp. space for EXPO. */
+ ep_nlimbs = esec? esize:0;
+ ep = ep_marker = mpi_alloc_limb_space( esize, esec );
+ MPN_COPY(ep, rp, esize);
+ }
+ if ( rp == mp )
+ {
+ /* RES and MOD are identical. Allocate temporary space for MOD.*/
+ gcry_assert (!mp_marker);
+ mp_nlimbs = msec?msize:0;
+ mp = mp_marker = mpi_alloc_limb_space( msize, msec );
+ MPN_COPY(mp, rp, msize);
+ }
+
+ /* Copy base to the result. */
+ if (res->alloced < size)
+ {
+ mpi_resize (res, size);
+ rp = res->d;
+ }
+ MPN_COPY ( rp, bp, bsize );
+ rsize = bsize;
+ rsign = bsign;
+
+ /* Main processing. */
+ {
+ mpi_size_t i;
+ mpi_ptr_t xp;
+ int c;
+ mpi_limb_t e;
+ mpi_limb_t carry_limb;
+ struct karatsuba_ctx karactx;
+
+ xp_nlimbs = msec? (2 * (msize + 1)):0;
+ xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
+
+ memset( &karactx, 0, sizeof karactx );
+ negative_result = (ep[0] & 1) && base->sign;
+
+ i = esize - 1;
+ e = ep[i];
+ count_leading_zeros (c, e);
+ e = (e << c) << 1; /* Shift the expo bits to the left, lose msb. */
+ c = BITS_PER_MPI_LIMB - 1 - c;
+
+ /* Main loop.
+
+ Make the result be pointed to alternately by XP and RP. This
+ helps us avoid block copying, which would otherwise be
+ necessary with the overlap restrictions of
+ _gcry_mpih_divmod. With 50% probability the result after this
+ loop will be in the area originally pointed by RP (==RES->d),
+ and with 50% probability in the area originally pointed to by XP. */
+ for (;;)
+ {
+ while (c)
+ {
+ mpi_ptr_t tp;
+ mpi_size_t xsize;
+
+ /*mpih_mul_n(xp, rp, rp, rsize);*/
+ if ( rsize < KARATSUBA_THRESHOLD )
+ _gcry_mpih_sqr_n_basecase( xp, rp, rsize );
+ else
+ {
+ if ( !tspace )
+ {
+ tsize = 2 * rsize;
+ tspace = mpi_alloc_limb_space( tsize, 0 );
+ }
+ else if ( tsize < (2*rsize) )
+ {
+ _gcry_mpi_free_limb_space (tspace, 0);
+ tsize = 2 * rsize;
+ tspace = mpi_alloc_limb_space (tsize, 0 );
+ }
+ _gcry_mpih_sqr_n (xp, rp, rsize, tspace);
+ }
+
+ xsize = 2 * rsize;
+ if ( xsize > msize )
+ {
+ _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+
+ if ( (mpi_limb_signed_t)e < 0 )
+ {
+ /*mpih_mul( xp, rp, rsize, bp, bsize );*/
+ if( bsize < KARATSUBA_THRESHOLD )
+ _gcry_mpih_mul ( xp, rp, rsize, bp, bsize );
+ else
+ _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, bp, bsize,
+ &karactx);
+
+ xsize = rsize + bsize;
+ if ( xsize > msize )
+ {
+ _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+ e <<= 1;
+ c--;
+ }
+
+ i--;
+ if ( i < 0 )
+ break;
+ e = ep[i];
+ c = BITS_PER_MPI_LIMB;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left
+ MOD_SHIFT_CNT steps. Adjust the result by reducing it with the
+ original MOD.
+
+ Also make sure the result is put in RES->d (where it already
+ might be, see above). */
+ if ( mod_shift_cnt )
+ {
+ carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
+ rp = res->d;
+ if ( carry_limb )
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ }
+ else if (res->d != rp)
+ {
+ MPN_COPY (res->d, rp, rsize);
+ rp = res->d;
+ }
+
+ if ( rsize >= msize )
+ {
+ _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
+ rsize = msize;
+ }
+
+ /* Remove any leading zero words from the result. */
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
+ MPN_NORMALIZE (rp, rsize);
+
+ _gcry_mpih_release_karatsuba_ctx (&karactx );
+ }
+
+ /* Fixup for negative results. */
+ if ( negative_result && rsize )
+ {
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt);
+ _gcry_mpih_sub( rp, mp, msize, rp, rsize);
+ rsize = msize;
+ rsign = msign;
+ MPN_NORMALIZE(rp, rsize);
+ }
+ gcry_assert (res->d == rp);
+ res->nlimbs = rsize;
+ res->sign = rsign;
+
+ leave:
+ if (mp_marker)
+ _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
+ if (bp_marker)
+ _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs );
+ if (ep_marker)
+ _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs );
+ if (xp_marker)
+ _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs );
+ if (tspace)
+ _gcry_mpi_free_limb_space( tspace, 0 );
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpi-scan.c b/grub-core/lib/libgcrypt/mpi/mpi-scan.c
new file mode 100644
index 0000000..2473cd9
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpi-scan.c
@@ -0,0 +1,130 @@
+/* mpi-scan.c - MPI functions
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+/****************
+ * Scan through an mpi and return byte for byte. a -1 is returned to indicate
+ * the end of the mpi. Scanning is done from the lsb to the msb, returned
+ * values are in the range of 0 .. 255.
+ *
+ * FIXME: This code is VERY ugly!
+ */
+int
+_gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx )
+{
+ int i, j;
+ unsigned n;
+ mpi_ptr_t ap;
+ mpi_limb_t limb;
+
+ ap = a->d;
+ for(n=0,i=0; i < a->nlimbs; i++ ) {
+ limb = ap[i];
+ for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
+ if( n == idx )
+ return (limb >> j*8) & 0xff;
+ }
+ return -1;
+}
+
+
+/****************
+ * Put a value at position IDX into A. idx counts from lsb to msb
+ */
+void
+_gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc )
+{
+ int i, j;
+ unsigned n;
+ mpi_ptr_t ap;
+ mpi_limb_t limb, c;
+
+ c = xc & 0xff;
+ ap = a->d;
+ for(n=0,i=0; i < a->alloced; i++ ) {
+ limb = ap[i];
+ for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
+ if( n == idx ) {
+ #if BYTES_PER_MPI_LIMB == 4
+ if( j == 0 )
+ limb = (limb & 0xffffff00) | c;
+ else if( j == 1 )
+ limb = (limb & 0xffff00ff) | (c<<8);
+ else if( j == 2 )
+ limb = (limb & 0xff00ffff) | (c<<16);
+ else
+ limb = (limb & 0x00ffffff) | (c<<24);
+ #elif BYTES_PER_MPI_LIMB == 8
+ if( j == 0 )
+ limb = (limb & 0xffffffffffffff00) | c;
+ else if( j == 1 )
+ limb = (limb & 0xffffffffffff00ff) | (c<<8);
+ else if( j == 2 )
+ limb = (limb & 0xffffffffff00ffff) | (c<<16);
+ else if( j == 3 )
+ limb = (limb & 0xffffffff00ffffff) | (c<<24);
+ else if( j == 4 )
+ limb = (limb & 0xffffff00ffffffff) | (c<<32);
+ else if( j == 5 )
+ limb = (limb & 0xffff00ffffffffff) | (c<<40);
+ else if( j == 6 )
+ limb = (limb & 0xff00ffffffffffff) | (c<<48);
+ else
+ limb = (limb & 0x00ffffffffffffff) | (c<<56);
+ #else
+ #error please enhance this function, its ugly - i know.
+ #endif
+ if( a->nlimbs <= i )
+ a->nlimbs = i+1;
+ ap[i] = limb;
+ return;
+ }
+ }
+ abort(); /* index out of range */
+}
+
+
+/****************
+ * Count the number of zerobits at the low end of A
+ */
+unsigned
+_gcry_mpi_trailing_zeros( gcry_mpi_t a )
+{
+ unsigned n, count = 0;
+
+ for(n=0; n < a->nlimbs; n++ ) {
+ if( a->d[n] ) {
+ unsigned nn;
+ mpi_limb_t alimb = a->d[n];
+
+ count_trailing_zeros( nn, alimb );
+ count += nn;
+ break;
+ }
+ count += BITS_PER_MPI_LIMB;
+ }
+ return count;
+
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c
new file mode 100644
index 0000000..f499796
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c
@@ -0,0 +1,750 @@
+/* mpicoder.c - Coder for the external representation of MPIs
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "g10lib.h"
+
+#define MAX_EXTERN_MPI_BITS 16384
+
+/* Helper used to scan PGP style MPIs. Returns NULL on failure. */
+static gcry_mpi_t
+mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
+ int secure)
+{
+ int i, j;
+ unsigned int nbits, nbytes, nlimbs, nread=0;
+ mpi_limb_t a;
+ gcry_mpi_t val = MPI_NULL;
+
+ if ( *ret_nread < 2 )
+ goto leave;
+ nbits = buffer[0] << 8 | buffer[1];
+ if ( nbits > MAX_EXTERN_MPI_BITS )
+ {
+/* log_debug ("mpi too large (%u bits)\n", nbits); */
+ goto leave;
+ }
+ buffer += 2;
+ nread = 2;
+
+ nbytes = (nbits+7) / 8;
+ nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
+ val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
+ i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
+ i %= BYTES_PER_MPI_LIMB;
+ j= val->nlimbs = nlimbs;
+ val->sign = 0;
+ for ( ; j > 0; j-- )
+ {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++ )
+ {
+ if ( ++nread > *ret_nread )
+ {
+/* log_debug ("mpi larger than buffer"); */
+ mpi_free (val);
+ val = NULL;
+ goto leave;
+ }
+ a <<= 8;
+ a |= *buffer++;
+ }
+ i = 0;
+ val->d[j-1] = a;
+ }
+
+ leave:
+ *ret_nread = nread;
+ return val;
+}
+
+
+/****************
+ * Fill the mpi VAL from the hex string in STR.
+ */
+static int
+mpi_fromstr (gcry_mpi_t val, const char *str)
+{
+ int sign = 0;
+ int prepend_zero = 0;
+ int i, j, c, c1, c2;
+ unsigned int nbits, nbytes, nlimbs;
+ mpi_limb_t a;
+
+ if ( *str == '-' )
+ {
+ sign = 1;
+ str++;
+ }
+
+ /* Skip optional hex prefix. */
+ if ( *str == '0' && str[1] == 'x' )
+ str += 2;
+
+ nbits = 4 * strlen (str);
+ if ((nbits % 8))
+ prepend_zero = 1;
+
+ nbytes = (nbits+7) / 8;
+ nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
+
+ if ( val->alloced < nlimbs )
+ mpi_resize (val, nlimbs);
+
+ i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
+ i %= BYTES_PER_MPI_LIMB;
+ j = val->nlimbs = nlimbs;
+ val->sign = sign;
+ for (; j > 0; j--)
+ {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++)
+ {
+ if (prepend_zero)
+ {
+ c1 = '0';
+ prepend_zero = 0;
+ }
+ else
+ c1 = *str++;
+
+ if (!c1)
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ c2 = *str++;
+ if (!c2)
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ if ( c1 >= '0' && c1 <= '9' )
+ c = c1 - '0';
+ else if ( c1 >= 'a' && c1 <= 'f' )
+ c = c1 - 'a' + 10;
+ else if ( c1 >= 'A' && c1 <= 'F' )
+ c = c1 - 'A' + 10;
+ else
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ c <<= 4;
+ if ( c2 >= '0' && c2 <= '9' )
+ c |= c2 - '0';
+ else if( c2 >= 'a' && c2 <= 'f' )
+ c |= c2 - 'a' + 10;
+ else if( c2 >= 'A' && c2 <= 'F' )
+ c |= c2 - 'A' + 10;
+ else
+ {
+ mpi_clear(val);
+ return 1; /* Error. */
+ }
+ a <<= 8;
+ a |= c;
+ }
+ i = 0;
+ val->d[j-1] = a;
+ }
+
+ return 0; /* Okay. */
+}
+
+
+/* Dump the value of A in a format suitable for debugging to
+ Libgcrypt's logging stream. Note that one leading space but no
+ trailing space or linefeed will be printed. It is okay to pass
+ NULL for A. */
+void
+gcry_mpi_dump (const gcry_mpi_t a)
+{
+ int i;
+
+ log_printf (" ");
+ if (!a)
+ log_printf ("[MPI_NULL]");
+ else
+ {
+ if (a->sign)
+ log_printf ( "-");
+#if BYTES_PER_MPI_LIMB == 2
+# define X "4"
+#elif BYTES_PER_MPI_LIMB == 4
+# define X "8"
+#elif BYTES_PER_MPI_LIMB == 8
+# define X "16"
+#elif BYTES_PER_MPI_LIMB == 16
+# define X "32"
+#else
+# error please define the format here
+#endif
+ for (i=a->nlimbs; i > 0 ; i-- )
+ {
+ log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
+ }
+#undef X
+ if (!a->nlimbs)
+ log_printf ("0");
+ }
+}
+
+/* Convience function used internally. */
+void
+_gcry_log_mpidump (const char *text, gcry_mpi_t a)
+{
+ log_printf ("%s:", text);
+ gcry_mpi_dump (a);
+ log_printf ("\n");
+}
+
+
+/* Return an allocated buffer with the MPI (msb first). NBYTES
+ receives the length of this buffer. Caller must free the return
+ string. This function returns an allocated buffer with NBYTES set
+ to zero if the value of A is zero. If sign is not NULL, it will be
+ set to the sign of the A. On error NULL is returned and ERRNO set
+ appropriately. */
+static unsigned char *
+do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
+{
+ unsigned char *p, *buffer;
+ mpi_limb_t alimb;
+ int i;
+ size_t n;
+
+ if (sign)
+ *sign = a->sign;
+
+ *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
+ n = *nbytes? *nbytes:1; /* Allocate at least one byte. */
+ p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n)
+ : gcry_malloc (n);
+ if (!buffer)
+ return NULL;
+
+ for (i=a->nlimbs-1; i >= 0; i--)
+ {
+ alimb = a->d[i];
+#if BYTES_PER_MPI_LIMB == 4
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb ;
+#elif BYTES_PER_MPI_LIMB == 8
+ *p++ = alimb >> 56;
+ *p++ = alimb >> 48;
+ *p++ = alimb >> 40;
+ *p++ = alimb >> 32;
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb ;
+#else
+# error please implement for this limb size.
+#endif
+ }
+
+ /* This is sub-optimal but we need to do the shift operation because
+ the caller has to free the returned buffer. */
+ for (p=buffer; !*p && *nbytes; p++, --*nbytes)
+ ;
+ if (p != buffer)
+ memmove (buffer,p, *nbytes);
+ return buffer;
+}
+
+
+byte *
+_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign)
+{
+ return do_get_buffer (a, nbytes, sign, 0);
+}
+
+byte *
+_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign)
+{
+ return do_get_buffer (a, nbytes, sign, 1);
+}
+
+
+/*
+ * Use the NBYTES at BUFFER_ARG to update A. Set the sign of a to
+ * SIGN.
+ */
+void
+_gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
+ unsigned int nbytes, int sign)
+{
+ const unsigned char *buffer = (const unsigned char*)buffer_arg;
+ const unsigned char *p;
+ mpi_limb_t alimb;
+ int nlimbs;
+ int i;
+
+ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
+ RESIZE_IF_NEEDED(a, nlimbs);
+ a->sign = sign;
+
+ for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
+ {
+#if BYTES_PER_MPI_LIMB == 4
+ alimb = *p-- ;
+ alimb |= *p-- << 8 ;
+ alimb |= *p-- << 16 ;
+ alimb |= *p-- << 24 ;
+#elif BYTES_PER_MPI_LIMB == 8
+ alimb = (mpi_limb_t)*p-- ;
+ alimb |= (mpi_limb_t)*p-- << 8 ;
+ alimb |= (mpi_limb_t)*p-- << 16 ;
+ alimb |= (mpi_limb_t)*p-- << 24 ;
+ alimb |= (mpi_limb_t)*p-- << 32 ;
+ alimb |= (mpi_limb_t)*p-- << 40 ;
+ alimb |= (mpi_limb_t)*p-- << 48 ;
+ alimb |= (mpi_limb_t)*p-- << 56 ;
+#else
+# error please implement for this limb size.
+#endif
+ a->d[i++] = alimb;
+ }
+ if ( p >= buffer )
+ {
+#if BYTES_PER_MPI_LIMB == 4
+ alimb = *p--;
+ if (p >= buffer)
+ alimb |= *p-- << 8;
+ if (p >= buffer)
+ alimb |= *p-- << 16;
+ if (p >= buffer)
+ alimb |= *p-- << 24;
+#elif BYTES_PER_MPI_LIMB == 8
+ alimb = (mpi_limb_t)*p--;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 8;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 16;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 24;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 32;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 40;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 48;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 56;
+#else
+# error please implement for this limb size.
+#endif
+ a->d[i++] = alimb;
+ }
+ a->nlimbs = i;
+ gcry_assert (i == nlimbs);
+}
+
+
+/* Convert the external representation of an integer stored in BUFFER
+ with a length of BUFLEN into a newly create MPI returned in
+ RET_MPI. If NBYTES is not NULL, it will receive the number of
+ bytes actually scanned after a successful operation. */
+gcry_error_t
+gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
+ const void *buffer_arg, size_t buflen, size_t *nscanned)
+{
+ const unsigned char *buffer = (const unsigned char*)buffer_arg;
+ struct gcry_mpi *a = NULL;
+ unsigned int len;
+ int secure = (buffer && gcry_is_secure (buffer));
+
+ if (format == GCRYMPI_FMT_SSH)
+ len = 0;
+ else
+ len = buflen;
+
+ if (format == GCRYMPI_FMT_STD)
+ {
+ const unsigned char *s = buffer;
+
+ a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+ if (len)
+ {
+ a->sign = !!(*s & 0x80);
+ if (a->sign)
+ {
+ /* FIXME: we have to convert from 2compl to magnitude format */
+ mpi_free (a);
+ return gcry_error (GPG_ERR_INTERNAL);
+ }
+ else
+ _gcry_mpi_set_buffer (a, s, len, 0);
+ }
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_USG)
+ {
+ a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+
+ if (len)
+ _gcry_mpi_set_buffer (a, buffer, len, 0);
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_PGP)
+ {
+ a = mpi_read_from_buffer (buffer, &len, secure);
+ if (nscanned)
+ *nscanned = len;
+ if (ret_mpi && a)
+ {
+ mpi_normalize (a);
+ *ret_mpi = a;
+ }
+ else if (a)
+ {
+ mpi_free(a);
+ a = NULL;
+ }
+ return a? 0 : gcry_error (GPG_ERR_INV_OBJ);
+ }
+ else if (format == GCRYMPI_FMT_SSH)
+ {
+ const unsigned char *s = buffer;
+ size_t n;
+
+ /* This test is not strictly necessary and an assert (!len)
+ would be sufficient. We keep this test in case we later
+ allow the BUFLEN argument to act as a sanitiy check. Same
+ below. */
+ if (len && len < 4)
+ return gcry_error (GPG_ERR_TOO_SHORT);
+
+ n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
+ s += 4;
+ if (len)
+ len -= 4;
+ if (len && n > len)
+ return gcry_error (GPG_ERR_TOO_LARGE);
+
+ a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+ if (n)
+ {
+ a->sign = !!(*s & 0x80);
+ if (a->sign)
+ {
+ /* FIXME: we have to convert from 2compl to magnitude format */
+ mpi_free(a);
+ return gcry_error (GPG_ERR_INTERNAL);
+ }
+ else
+ _gcry_mpi_set_buffer( a, s, n, 0 );
+ }
+ if (nscanned)
+ *nscanned = n+4;
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_HEX)
+ {
+ /* We can only handle C strings for now. */
+ if (buflen)
+ return gcry_error (GPG_ERR_INV_ARG);
+
+ a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
+ if (mpi_fromstr (a, (const char *)buffer))
+ {
+ mpi_free (a);
+ return gcry_error (GPG_ERR_INV_OBJ);
+ }
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else
+ return gcry_error (GPG_ERR_INV_ARG);
+}
+
+
+/* Convert the big integer A into the external representation
+ described by FORMAT and store it in the provided BUFFER which has
+ been allocated by the user with a size of BUFLEN bytes. NWRITTEN
+ receives the actual length of the external representation unless it
+ has been passed as NULL. BUFFER may be NULL to query the required
+ length. */
+gcry_error_t
+gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten, struct gcry_mpi *a)
+{
+ unsigned int nbits = mpi_get_nbits (a);
+ size_t len;
+ size_t dummy_nwritten;
+
+ if (!nwritten)
+ nwritten = &dummy_nwritten;
+
+ len = buflen;
+ *nwritten = 0;
+ if (format == GCRYMPI_FMT_STD)
+ {
+ unsigned char *tmp;
+ int extra = 0;
+ unsigned int n;
+
+ if (a->sign)
+ return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ if (n && (*tmp & 0x80))
+ {
+ n++;
+ extra=1;
+ }
+
+ if (buffer && n > len)
+ {
+ /* The provided buffer is too short. */
+ gcry_free (tmp);
+ return gcry_error (GPG_ERR_TOO_SHORT);
+ }
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ if (extra)
+ *s++ = 0;
+ memcpy (s, tmp, n-extra);
+ }
+ gcry_free(tmp);
+ *nwritten = n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_USG)
+ {
+ unsigned int n = (nbits + 7)/8;
+
+ /* Note: We ignore the sign for this format. */
+ /* FIXME: for performance reasons we should put this into
+ mpi_aprint because we can then use the buffer directly. */
+ if (buffer && n > len)
+ return gcry_error (GPG_ERR_TOO_SHORT);
+ if (buffer)
+ {
+ unsigned char *tmp;
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ memcpy (buffer, tmp, n);
+ gcry_free (tmp);
+ }
+ *nwritten = n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_PGP)
+ {
+ unsigned int n = (nbits + 7)/8;
+
+ /* The PGP format can only handle unsigned integers. */
+ if( a->sign )
+ return gcry_error (GPG_ERR_INV_ARG);
+
+ if (buffer && n+2 > len)
+ return gcry_error (GPG_ERR_TOO_SHORT);
+
+ if (buffer)
+ {
+ unsigned char *tmp;
+ unsigned char *s = buffer;
+
+ s[0] = nbits >> 8;
+ s[1] = nbits;
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ memcpy (s+2, tmp, n);
+ gcry_free (tmp);
+ }
+ *nwritten = n+2;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_SSH)
+ {
+ unsigned char *tmp;
+ int extra = 0;
+ unsigned int n;
+
+ if (a->sign)
+ return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ if (n && (*tmp & 0x80))
+ {
+ n++;
+ extra=1;
+ }
+
+ if (buffer && n+4 > len)
+ {
+ gcry_free(tmp);
+ return gcry_error (GPG_ERR_TOO_SHORT);
+ }
+
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ *s++ = n >> 24;
+ *s++ = n >> 16;
+ *s++ = n >> 8;
+ *s++ = n;
+ if (extra)
+ *s++ = 0;
+
+ memcpy (s, tmp, n-extra);
+ }
+ gcry_free (tmp);
+ *nwritten = 4+n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_HEX)
+ {
+ unsigned char *tmp;
+ int i;
+ int extra = 0;
+ unsigned int n = 0;
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ if (!n || (*tmp & 0x80))
+ extra = 2;
+
+ if (buffer && 2*n + extra + !!a->sign + 1 > len)
+ {
+ gcry_free(tmp);
+ return gcry_error (GPG_ERR_TOO_SHORT);
+ }
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ if (a->sign)
+ *s++ = '-';
+ if (extra)
+ {
+ *s++ = '0';
+ *s++ = '0';
+ }
+
+ for (i=0; i < n; i++)
+ {
+ unsigned int c = tmp[i];
+
+ *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
+ c &= 15;
+ *s++ = c < 10? '0'+c : 'A'+c-10 ;
+ }
+ *s++ = 0;
+ *nwritten = s - buffer;
+ }
+ else
+ {
+ *nwritten = 2*n + extra + !!a->sign + 1;
+ }
+ gcry_free (tmp);
+ return 0;
+ }
+ else
+ return gcry_error (GPG_ERR_INV_ARG);
+}
+
+
+/*
+ * Like gcry_mpi_print but this function allocates the buffer itself.
+ * The caller has to supply the address of a pointer. NWRITTEN may be
+ * NULL.
+ */
+gcry_error_t
+gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ struct gcry_mpi *a)
+{
+ size_t n;
+ gcry_error_t rc;
+
+ *buffer = NULL;
+ rc = gcry_mpi_print (format, NULL, 0, &n, a);
+ if (rc)
+ return rc;
+
+ *buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n);
+ if (!*buffer)
+ return gpg_error_from_syserror ();
+ rc = gcry_mpi_print( format, *buffer, n, &n, a );
+ if (rc)
+ {
+ gcry_free(*buffer);
+ *buffer = NULL;
+ }
+ else if (nwritten)
+ *nwritten = n;
+ return rc;
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpih-div.c b/grub-core/lib/libgcrypt/mpi/mpih-div.c
new file mode 100644
index 0000000..224b810
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpih-div.c
@@ -0,0 +1,533 @@
+/* mpih-div.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2000,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+/* FIXME: We should be using invert_limb (or invert_normalized_limb)
+ * here (not udiv_qrnnd).
+ */
+
+mpi_limb_t
+_gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb)
+{
+ mpi_size_t i;
+ mpi_limb_t n1, n0, r;
+ int dummy;
+
+ /* Botch: Should this be handled at all? Rely on callers? */
+ if( !dividend_size )
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ * dividend is large, pre-invert the divisor, and use
+ * only multiplications in the inner loop.
+ *
+ * This test should be read:
+ * Does it ever help to use udiv_qrnnd_preinv?
+ * && Does what we save compensate for the inversion overhead?
+ */
+ if( UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
+ int normalization_steps;
+
+ count_leading_zeros( normalization_steps, divisor_limb );
+ if( normalization_steps ) {
+ mpi_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ *
+ * Special case for DIVISOR_LIMB == 100...000.
+ */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ UDIV_QRNND_PREINV(dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else {
+ mpi_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ *
+ * Special case for DIVISOR_LIMB == 100...000.
+ */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if( r >= divisor_limb )
+ r = 0;
+ else
+ i--;
+
+ for( ; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(dummy, r, r,
+ n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+ }
+ }
+ else {
+ if( UDIV_NEEDS_NORMALIZATION ) {
+ int normalization_steps;
+
+ count_leading_zeros(normalization_steps, divisor_limb);
+ if( normalization_steps ) {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for(i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ * it, or because DIVISOR_LIMB is already normalized. */
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if(r >= divisor_limb)
+ r = 0;
+ else
+ i--;
+
+ for(; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r, n0, divisor_limb);
+ }
+ return r;
+ }
+}
+
+/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
+ * the NSIZE-DSIZE least significant quotient limbs at QP
+ * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is
+ * non-zero, generate that many fraction bits and append them after the
+ * other quotient limbs.
+ * Return the most significant limb of the quotient, this is always 0 or 1.
+ *
+ * Preconditions:
+ * 0. NSIZE >= DSIZE.
+ * 1. The most significant bit of the divisor must be set.
+ * 2. QP must either not overlap with the input operands at all, or
+ * QP + DSIZE >= NP must hold true. (This means that it's
+ * possible to put the quotient in the high part of NUM, right after the
+ * remainder in NUM.
+ * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero.
+ */
+
+mpi_limb_t
+_gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
+ mpi_ptr_t np, mpi_size_t nsize,
+ mpi_ptr_t dp, mpi_size_t dsize)
+{
+ mpi_limb_t most_significant_q_limb = 0;
+
+ switch(dsize) {
+ case 0:
+ /* We are asked to divide by zero, so go ahead and do it! (To make
+ the compiler not remove this statement, return the value.) */
+ return 1 / dsize;
+
+ case 1:
+ {
+ mpi_size_t i;
+ mpi_limb_t n1;
+ mpi_limb_t d;
+
+ d = dp[0];
+ n1 = np[nsize - 1];
+
+ if( n1 >= d ) {
+ n1 -= d;
+ most_significant_q_limb = 1;
+ }
+
+ qp += qextra_limbs;
+ for( i = nsize - 2; i >= 0; i--)
+ udiv_qrnnd( qp[i], n1, n1, np[i], d );
+ qp -= qextra_limbs;
+
+ for( i = qextra_limbs - 1; i >= 0; i-- )
+ udiv_qrnnd (qp[i], n1, n1, 0, d);
+
+ np[0] = n1;
+ }
+ break;
+
+ case 2:
+ {
+ mpi_size_t i;
+ mpi_limb_t n1, n0, n2;
+ mpi_limb_t d1, d0;
+
+ np += nsize - 2;
+ d1 = dp[1];
+ d0 = dp[0];
+ n1 = np[1];
+ n0 = np[0];
+
+ if( n1 >= d1 && (n1 > d1 || n0 >= d0) ) {
+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
+ most_significant_q_limb = 1;
+ }
+
+ for( i = qextra_limbs + nsize - 2 - 1; i >= 0; i-- ) {
+ mpi_limb_t q;
+ mpi_limb_t r;
+
+ if( i >= qextra_limbs )
+ np--;
+ else
+ np[0] = 0;
+
+ if( n1 == d1 ) {
+ /* Q should be either 111..111 or 111..110. Need special
+ * treatment of this rare case as normal division would
+ * give overflow. */
+ q = ~(mpi_limb_t)0;
+
+ r = n0 + d1;
+ if( r < d1 ) { /* Carry in the addition? */
+ add_ssaaaa( n1, n0, r - d0, np[0], 0, d0 );
+ qp[i] = q;
+ continue;
+ }
+ n1 = d0 - (d0 != 0?1:0);
+ n0 = -d0;
+ }
+ else {
+ udiv_qrnnd (q, r, n1, n0, d1);
+ umul_ppmm (n1, n0, d0, q);
+ }
+
+ n2 = np[0];
+ q_test:
+ if( n1 > r || (n1 == r && n0 > n2) ) {
+ /* The estimated Q was too large. */
+ q--;
+ sub_ddmmss (n1, n0, n1, n0, 0, d0);
+ r += d1;
+ if( r >= d1 ) /* If not carry, test Q again. */
+ goto q_test;
+ }
+
+ qp[i] = q;
+ sub_ddmmss (n1, n0, r, n2, n1, n0);
+ }
+ np[1] = n1;
+ np[0] = n0;
+ }
+ break;
+
+ default:
+ {
+ mpi_size_t i;
+ mpi_limb_t dX, d1, n0;
+
+ np += nsize - dsize;
+ dX = dp[dsize - 1];
+ d1 = dp[dsize - 2];
+ n0 = np[dsize - 1];
+
+ if( n0 >= dX ) {
+ if(n0 > dX || _gcry_mpih_cmp(np, dp, dsize - 1) >= 0 ) {
+ _gcry_mpih_sub_n(np, np, dp, dsize);
+ n0 = np[dsize - 1];
+ most_significant_q_limb = 1;
+ }
+ }
+
+ for( i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) {
+ mpi_limb_t q;
+ mpi_limb_t n1, n2;
+ mpi_limb_t cy_limb;
+
+ if( i >= qextra_limbs ) {
+ np--;
+ n2 = np[dsize];
+ }
+ else {
+ n2 = np[dsize - 1];
+ MPN_COPY_DECR (np + 1, np, dsize - 1);
+ np[0] = 0;
+ }
+
+ if( n0 == dX ) {
+ /* This might over-estimate q, but it's probably not worth
+ * the extra code here to find out. */
+ q = ~(mpi_limb_t)0;
+ }
+ else {
+ mpi_limb_t r;
+
+ udiv_qrnnd(q, r, n0, np[dsize - 1], dX);
+ umul_ppmm(n1, n0, d1, q);
+
+ while( n1 > r || (n1 == r && n0 > np[dsize - 2])) {
+ q--;
+ r += dX;
+ if( r < dX ) /* I.e. "carry in previous addition?" */
+ break;
+ n1 -= n0 < d1;
+ n0 -= d1;
+ }
+ }
+
+ /* Possible optimization: We already have (q * n0) and (1 * n1)
+ * after the calculation of q. Taking advantage of that, we
+ * could make this loop make two iterations less. */
+ cy_limb = _gcry_mpih_submul_1(np, dp, dsize, q);
+
+ if( n2 != cy_limb ) {
+ _gcry_mpih_add_n(np, np, dp, dsize);
+ q--;
+ }
+
+ qp[i] = q;
+ n0 = np[dsize - 1];
+ }
+ }
+ }
+
+ return most_significant_q_limb;
+}
+
+
+/****************
+ * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
+ * Return the single-limb remainder.
+ * There are no constraints on the value of the divisor.
+ *
+ * QUOT_PTR and DIVIDEND_PTR might point to the same limb.
+ */
+
+mpi_limb_t
+_gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
+ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb)
+{
+ mpi_size_t i;
+ mpi_limb_t n1, n0, r;
+ int dummy;
+
+ if( !dividend_size )
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ * dividend is large, pre-invert the divisor, and use
+ * only multiplications in the inner loop.
+ *
+ * This test should be read:
+ * Does it ever help to use udiv_qrnnd_preinv?
+ * && Does what we save compensate for the inversion overhead?
+ */
+ if( UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
+ int normalization_steps;
+
+ count_leading_zeros( normalization_steps, divisor_limb );
+ if( normalization_steps ) {
+ mpi_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ */
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV( quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ UDIV_QRNND_PREINV( quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else {
+ mpi_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ */
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t) 0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if( r >= divisor_limb )
+ r = 0;
+ else
+ quot_ptr[i--] = 0;
+
+ for( ; i >= 0; i-- ) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV( quot_ptr[i], r, r,
+ n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+ }
+ }
+ else {
+ if(UDIV_NEEDS_NORMALIZATION) {
+ int normalization_steps;
+
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if( normalization_steps ) {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ * it, or because DIVISOR_LIMB is already normalized. */
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if(r >= divisor_limb)
+ r = 0;
+ else
+ quot_ptr[i--] = 0;
+
+ for(; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd( quot_ptr[i], r, r, n0, divisor_limb );
+ }
+ return r;
+ }
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpih-mul.c b/grub-core/lib/libgcrypt/mpi/mpih-mul.c
new file mode 100644
index 0000000..b8e0561
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpih-mul.c
@@ -0,0 +1,528 @@
+/* mpih-mul.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 1999, 2000,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if( (size) < KARATSUBA_THRESHOLD ) \
+ mul_n_basecase (prodp, up, vp, size); \
+ else \
+ mul_n (prodp, up, vp, size, tspace); \
+ } while (0);
+
+#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
+ do { \
+ if ((size) < KARATSUBA_THRESHOLD) \
+ _gcry_mpih_sqr_n_basecase (prodp, up, size); \
+ else \
+ _gcry_mpih_sqr_n (prodp, up, size, tspace); \
+ } while (0);
+
+
+
+
+/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
+ * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
+ * always stored. Return the most significant limb.
+ *
+ * Argument constraints:
+ * 1. PRODP != UP and PRODP != VP, i.e. the destination
+ * must be distinct from the multiplier and the multiplicand.
+ *
+ *
+ * Handle simple cases with traditional multiplication.
+ *
+ * This is the most critical code of multiplication. All multiplies rely
+ * on this, both small and huge. Small ones arrive here immediately. Huge
+ * ones arrive here as this is the base case for Karatsuba's recursive
+ * algorithm below.
+ */
+
+static mpi_limb_t
+mul_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up,
+ mpi_ptr_t vp, mpi_size_t size)
+{
+ mpi_size_t i;
+ mpi_limb_t cy;
+ mpi_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, size );
+ else
+ MPN_ZERO( prodp, size );
+ cy = 0;
+ }
+ else
+ cy = _gcry_mpih_mul_1( prodp, up, size, v_limb );
+
+ prodp[size] = cy;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i = 1; i < size; i++ ) {
+ v_limb = vp[i];
+ if( v_limb <= 1 ) {
+ cy = 0;
+ if( v_limb == 1 )
+ cy = _gcry_mpih_add_n(prodp, prodp, up, size);
+ }
+ else
+ cy = _gcry_mpih_addmul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy;
+ prodp++;
+ }
+
+ return cy;
+}
+
+
+static void
+mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t size, mpi_ptr_t tspace )
+{
+ if( size & 1 ) {
+ /* The size is odd, and the code below doesn't handle that.
+ * Multiply the least significant (size - 1) limbs with a recursive
+ * call, and handle the most significant limb of S1 and S2
+ * separately.
+ * A slightly faster way to do this would be to make the Karatsuba
+ * code below behave as if the size were even, and let it check for
+ * odd size in the end. I.e., in essence move this code to the end.
+ * Doing so would save us a recursive call, and potentially make the
+ * stack grow a lot less.
+ */
+ mpi_size_t esize = size - 1; /* even size */
+ mpi_limb_t cy_limb;
+
+ MPN_MUL_N_RECURSE( prodp, up, vp, esize, tspace );
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, vp[esize] );
+ prodp[esize + esize] = cy_limb;
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, vp, size, up[esize] );
+ prodp[esize + size] = cy_limb;
+ }
+ else {
+ /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
+ *
+ * Split U in two pieces, U1 and U0, such that
+ * U = U0 + U1*(B**n),
+ * and V in V1 and V0, such that
+ * V = V0 + V1*(B**n).
+ *
+ * UV is then computed recursively using the identity
+ *
+ * 2n n n n
+ * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
+ * 1 1 1 0 0 1 0 0
+ *
+ * Where B = 2**BITS_PER_MP_LIMB.
+ */
+ mpi_size_t hsize = size >> 1;
+ mpi_limb_t cy;
+ int negflg;
+
+ /* Product H. ________________ ________________
+ * |_____U1 x V1____||____U0 x V0_____|
+ * Put result in upper part of PROD and pass low part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize, tspace);
+
+ /* Product M. ________________
+ * |_(U1-U0)(V0-V1)_|
+ */
+ if( _gcry_mpih_cmp(up + hsize, up, hsize) >= 0 ) {
+ _gcry_mpih_sub_n(prodp, up + hsize, up, hsize);
+ negflg = 0;
+ }
+ else {
+ _gcry_mpih_sub_n(prodp, up, up + hsize, hsize);
+ negflg = 1;
+ }
+ if( _gcry_mpih_cmp(vp + hsize, vp, hsize) >= 0 ) {
+ _gcry_mpih_sub_n(prodp + hsize, vp + hsize, vp, hsize);
+ negflg ^= 1;
+ }
+ else {
+ _gcry_mpih_sub_n(prodp + hsize, vp, vp + hsize, hsize);
+ /* No change of NEGFLG. */
+ }
+ /* Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize, tspace + size);
+
+ /* Add/copy product H. */
+ MPN_COPY (prodp + hsize, prodp + size, hsize);
+ cy = _gcry_mpih_add_n( prodp + size, prodp + size,
+ prodp + size + hsize, hsize);
+
+ /* Add product M (if NEGFLG M is a negative number) */
+ if(negflg)
+ cy -= _gcry_mpih_sub_n(prodp + hsize, prodp + hsize, tspace, size);
+ else
+ cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size);
+
+ /* Product L. ________________ ________________
+ * |________________||____U0 x V0_____|
+ * Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size);
+
+ /* Add/copy Product L (twice) */
+
+ cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size);
+ if( cy )
+ _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size, hsize, cy);
+
+ MPN_COPY(prodp, tspace, hsize);
+ cy = _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace + hsize, hsize);
+ if( cy )
+ _gcry_mpih_add_1(prodp + size, prodp + size, size, 1);
+ }
+}
+
+
+void
+_gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size )
+{
+ mpi_size_t i;
+ mpi_limb_t cy_limb;
+ mpi_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = up[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, size );
+ else
+ MPN_ZERO(prodp, size);
+ cy_limb = 0;
+ }
+ else
+ cy_limb = _gcry_mpih_mul_1( prodp, up, size, v_limb );
+
+ prodp[size] = cy_limb;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i=1; i < size; i++) {
+ v_limb = up[i];
+ if( v_limb <= 1 ) {
+ cy_limb = 0;
+ if( v_limb == 1 )
+ cy_limb = _gcry_mpih_add_n(prodp, prodp, up, size);
+ }
+ else
+ cy_limb = _gcry_mpih_addmul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+ }
+}
+
+
+void
+_gcry_mpih_sqr_n( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace)
+{
+ if( size & 1 ) {
+ /* The size is odd, and the code below doesn't handle that.
+ * Multiply the least significant (size - 1) limbs with a recursive
+ * call, and handle the most significant limb of S1 and S2
+ * separately.
+ * A slightly faster way to do this would be to make the Karatsuba
+ * code below behave as if the size were even, and let it check for
+ * odd size in the end. I.e., in essence move this code to the end.
+ * Doing so would save us a recursive call, and potentially make the
+ * stack grow a lot less.
+ */
+ mpi_size_t esize = size - 1; /* even size */
+ mpi_limb_t cy_limb;
+
+ MPN_SQR_N_RECURSE( prodp, up, esize, tspace );
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, up[esize] );
+ prodp[esize + esize] = cy_limb;
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, size, up[esize] );
+
+ prodp[esize + size] = cy_limb;
+ }
+ else {
+ mpi_size_t hsize = size >> 1;
+ mpi_limb_t cy;
+
+ /* Product H. ________________ ________________
+ * |_____U1 x U1____||____U0 x U0_____|
+ * Put result in upper part of PROD and pass low part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace);
+
+ /* Product M. ________________
+ * |_(U1-U0)(U0-U1)_|
+ */
+ if( _gcry_mpih_cmp( up + hsize, up, hsize) >= 0 )
+ _gcry_mpih_sub_n( prodp, up + hsize, up, hsize);
+ else
+ _gcry_mpih_sub_n (prodp, up, up + hsize, hsize);
+
+ /* Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE. */
+ MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size);
+
+ /* Add/copy product H */
+ MPN_COPY(prodp + hsize, prodp + size, hsize);
+ cy = _gcry_mpih_add_n(prodp + size, prodp + size,
+ prodp + size + hsize, hsize);
+
+ /* Add product M (if NEGFLG M is a negative number). */
+ cy -= _gcry_mpih_sub_n (prodp + hsize, prodp + hsize, tspace, size);
+
+ /* Product L. ________________ ________________
+ * |________________||____U0 x U0_____|
+ * Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE. */
+ MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size);
+
+ /* Add/copy Product L (twice). */
+ cy += _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace, size);
+ if( cy )
+ _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size,
+ hsize, cy);
+
+ MPN_COPY(prodp, tspace, hsize);
+ cy = _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
+ if( cy )
+ _gcry_mpih_add_1 (prodp + size, prodp + size, size, 1);
+ }
+}
+
+
+/* This should be made into an inline function in gmp.h. */
+void
+_gcry_mpih_mul_n( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size)
+{
+ int secure;
+
+ if( up == vp ) {
+ if( size < KARATSUBA_THRESHOLD )
+ _gcry_mpih_sqr_n_basecase( prodp, up, size );
+ else {
+ mpi_ptr_t tspace;
+ secure = gcry_is_secure( up );
+ tspace = mpi_alloc_limb_space( 2 * size, secure );
+ _gcry_mpih_sqr_n( prodp, up, size, tspace );
+ _gcry_mpi_free_limb_space (tspace, 2 * size );
+ }
+ }
+ else {
+ if( size < KARATSUBA_THRESHOLD )
+ mul_n_basecase( prodp, up, vp, size );
+ else {
+ mpi_ptr_t tspace;
+ secure = gcry_is_secure( up ) || gcry_is_secure( vp );
+ tspace = mpi_alloc_limb_space( 2 * size, secure );
+ mul_n (prodp, up, vp, size, tspace);
+ _gcry_mpi_free_limb_space (tspace, 2 * size );
+ }
+ }
+}
+
+
+
+void
+_gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize,
+ struct karatsuba_ctx *ctx )
+{
+ mpi_limb_t cy;
+
+ if( !ctx->tspace || ctx->tspace_size < vsize ) {
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ ctx->tspace_nlimbs = 2 * vsize;
+ ctx->tspace = mpi_alloc_limb_space( 2 * vsize,
+ (gcry_is_secure( up )
+ || gcry_is_secure( vp )) );
+ ctx->tspace_size = vsize;
+ }
+
+ MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace );
+
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ if( usize >= vsize ) {
+ if( !ctx->tp || ctx->tp_size < vsize ) {
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ ctx->tp_nlimbs = 2 * vsize;
+ ctx->tp = mpi_alloc_limb_space( 2 * vsize, gcry_is_secure( up )
+ || gcry_is_secure( vp ) );
+ ctx->tp_size = vsize;
+ }
+
+ do {
+ MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace );
+ cy = _gcry_mpih_add_n( prodp, prodp, ctx->tp, vsize );
+ _gcry_mpih_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy );
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ } while( usize >= vsize );
+ }
+
+ if( usize ) {
+ if( usize < KARATSUBA_THRESHOLD ) {
+ _gcry_mpih_mul( ctx->tspace, vp, vsize, up, usize );
+ }
+ else {
+ if( !ctx->next ) {
+ ctx->next = gcry_xcalloc( 1, sizeof *ctx );
+ }
+ _gcry_mpih_mul_karatsuba_case( ctx->tspace,
+ vp, vsize,
+ up, usize,
+ ctx->next );
+ }
+
+ cy = _gcry_mpih_add_n( prodp, prodp, ctx->tspace, vsize);
+ _gcry_mpih_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy );
+ }
+}
+
+
+void
+_gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx )
+{
+ struct karatsuba_ctx *ctx2;
+
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ for( ctx=ctx->next; ctx; ctx = ctx2 ) {
+ ctx2 = ctx->next;
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ gcry_free( ctx );
+ }
+}
+
+/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
+ * and v (pointed to by VP, with VSIZE limbs), and store the result at
+ * PRODP. USIZE + VSIZE limbs are always stored, but if the input
+ * operands are normalized. Return the most significant limb of the
+ * result.
+ *
+ * NOTE: The space pointed to by PRODP is overwritten before finished
+ * with U and V, so overlap is an error.
+ *
+ * Argument constraints:
+ * 1. USIZE >= VSIZE.
+ * 2. PRODP != UP and PRODP != VP, i.e. the destination
+ * must be distinct from the multiplier and the multiplicand.
+ */
+
+mpi_limb_t
+_gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize)
+{
+ mpi_ptr_t prod_endp = prodp + usize + vsize - 1;
+ mpi_limb_t cy;
+ struct karatsuba_ctx ctx;
+
+ if( vsize < KARATSUBA_THRESHOLD ) {
+ mpi_size_t i;
+ mpi_limb_t v_limb;
+
+ if( !vsize )
+ return 0;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, usize );
+ else
+ MPN_ZERO( prodp, usize );
+ cy = 0;
+ }
+ else
+ cy = _gcry_mpih_mul_1( prodp, up, usize, v_limb );
+
+ prodp[usize] = cy;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i = 1; i < vsize; i++ ) {
+ v_limb = vp[i];
+ if( v_limb <= 1 ) {
+ cy = 0;
+ if( v_limb == 1 )
+ cy = _gcry_mpih_add_n(prodp, prodp, up, usize);
+ }
+ else
+ cy = _gcry_mpih_addmul_1(prodp, up, usize, v_limb);
+
+ prodp[usize] = cy;
+ prodp++;
+ }
+
+ return cy;
+ }
+
+ memset( &ctx, 0, sizeof ctx );
+ _gcry_mpih_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx );
+ _gcry_mpih_release_karatsuba_ctx( &ctx );
+ return *prod_endp;
+}
diff --git a/grub-core/lib/libgcrypt/mpi/mpiutil.c b/grub-core/lib/libgcrypt/mpi/mpiutil.c
new file mode 100644
index 0000000..76630a6
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/mpiutil.c
@@ -0,0 +1,460 @@
+/* mpiutil.ac - Utility functions for MPI
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ * 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi-internal.h"
+#include "mod-source-info.h"
+
+
+const char *
+_gcry_mpi_get_hw_config (void)
+{
+ return mod_source_info + 1;
+}
+
+
+/****************
+ * Note: It was a bad idea to use the number of limbs to allocate
+ * because on a alpha the limbs are large but we normally need
+ * integers of n bits - So we should change this to bits (or bytes).
+ *
+ * But mpi_alloc is used in a lot of places :-(. New code
+ * should use mpi_new.
+ */
+gcry_mpi_t
+_gcry_mpi_alloc( unsigned nlimbs )
+{
+ gcry_mpi_t a;
+
+ a = gcry_xmalloc( sizeof *a );
+ a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
+ a->alloced = nlimbs;
+ a->nlimbs = 0;
+ a->sign = 0;
+ a->flags = 0;
+ return a;
+}
+
+void
+_gcry_mpi_m_check( gcry_mpi_t a )
+{
+ _gcry_check_heap(a);
+ _gcry_check_heap(a->d);
+}
+
+gcry_mpi_t
+_gcry_mpi_alloc_secure( unsigned nlimbs )
+{
+ gcry_mpi_t a;
+
+ a = gcry_xmalloc( sizeof *a );
+ a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
+ a->alloced = nlimbs;
+ a->flags = 1;
+ a->nlimbs = 0;
+ a->sign = 0;
+ return a;
+}
+
+
+
+mpi_ptr_t
+_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
+{
+ mpi_ptr_t p;
+ size_t len;
+
+ len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
+ p = secure ? gcry_xmalloc_secure (len) : gcry_xmalloc (len);
+ if (! nlimbs)
+ *p = 0;
+
+ return p;
+}
+
+void
+_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
+{
+ if (a)
+ {
+ size_t len = nlimbs * sizeof(mpi_limb_t);
+
+ /* If we have information on the number of allocated limbs, we
+ better wipe that space out. This is a failsafe feature if
+ secure memory has been disabled or was not properly
+ implemented in user provided allocation functions. */
+ if (len)
+ wipememory (a, len);
+ gcry_free(a);
+ }
+}
+
+
+void
+_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
+{
+ _gcry_mpi_free_limb_space (a->d, a->alloced);
+ a->d = ap;
+ a->alloced = nlimbs;
+}
+
+
+
+/****************
+ * Resize the array of A to NLIMBS. The additional space is cleared
+ * (set to 0).
+ */
+void
+_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
+{
+ size_t i;
+
+ if (nlimbs <= a->alloced)
+ {
+ /* We only need to clear the new space (this is a nop if the
+ limb space is already of the correct size. */
+ for (i=a->nlimbs; i < a->alloced; i++)
+ a->d[i] = 0;
+ return;
+ }
+
+ /* Actually resize the limb space. */
+ if (a->d)
+ {
+ a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
+ for (i=a->alloced; i < nlimbs; i++)
+ a->d[i] = 0;
+ }
+ else
+ {
+ if (a->flags & 1)
+ /* Secure memory is wanted. */
+ a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
+ else
+ /* Standard memory. */
+ a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t));
+ }
+ a->alloced = nlimbs;
+}
+
+void
+_gcry_mpi_clear( gcry_mpi_t a )
+{
+ a->nlimbs = 0;
+ a->flags = 0;
+}
+
+
+void
+_gcry_mpi_free( gcry_mpi_t a )
+{
+ if (!a )
+ return;
+ if ((a->flags & 4))
+ gcry_free( a->d );
+ else
+ {
+ _gcry_mpi_free_limb_space(a->d, a->alloced);
+ }
+ if ((a->flags & ~7))
+ log_bug("invalid flag value in mpi\n");
+ gcry_free(a);
+}
+
+static void
+mpi_set_secure( gcry_mpi_t a )
+{
+ mpi_ptr_t ap, bp;
+
+ if ( (a->flags & 1) )
+ return;
+ a->flags |= 1;
+ ap = a->d;
+ if (!a->nlimbs)
+ {
+ gcry_assert (!ap);
+ return;
+ }
+ bp = mpi_alloc_limb_space (a->nlimbs, 1);
+ MPN_COPY( bp, ap, a->nlimbs );
+ a->d = bp;
+ _gcry_mpi_free_limb_space (ap, a->alloced);
+}
+
+
+gcry_mpi_t
+gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
+{
+ if (!a)
+ a = mpi_alloc(0);
+
+ if( a->flags & 4 )
+ gcry_free( a->d );
+ else
+ _gcry_mpi_free_limb_space (a->d, a->alloced);
+
+ a->d = p;
+ a->alloced = 0;
+ a->nlimbs = 0;
+ a->sign = nbits;
+ a->flags = 4;
+ return a;
+}
+
+
+void *
+gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
+{
+ if( !(a->flags & 4) )
+ log_bug("mpi_get_opaque on normal mpi\n");
+ if( nbits )
+ *nbits = a->sign;
+ return a->d;
+}
+
+
+/****************
+ * Note: This copy function should not interpret the MPI
+ * but copy it transparently.
+ */
+gcry_mpi_t
+gcry_mpi_copy( gcry_mpi_t a )
+{
+ int i;
+ gcry_mpi_t b;
+
+ if( a && (a->flags & 4) ) {
+ void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
+ : gcry_xmalloc( (a->sign+7)/8 );
+ memcpy( p, a->d, (a->sign+7)/8 );
+ b = gcry_mpi_set_opaque( NULL, p, a->sign );
+ }
+ else if( a ) {
+ b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
+ : mpi_alloc( a->nlimbs );
+ b->nlimbs = a->nlimbs;
+ b->sign = a->sign;
+ b->flags = a->flags;
+ for(i=0; i < b->nlimbs; i++ )
+ b->d[i] = a->d[i];
+ }
+ else
+ b = NULL;
+ return b;
+}
+
+
+/****************
+ * This function allocates an MPI which is optimized to hold
+ * a value as large as the one given in the argument and allocates it
+ * with the same flags as A.
+ */
+gcry_mpi_t
+_gcry_mpi_alloc_like( gcry_mpi_t a )
+{
+ gcry_mpi_t b;
+
+ if( a && (a->flags & 4) ) {
+ int n = (a->sign+7)/8;
+ void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n )
+ : gcry_malloc( n );
+ memcpy( p, a->d, n );
+ b = gcry_mpi_set_opaque( NULL, p, a->sign );
+ }
+ else if( a ) {
+ b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
+ : mpi_alloc( a->nlimbs );
+ b->nlimbs = 0;
+ b->sign = 0;
+ b->flags = a->flags;
+ }
+ else
+ b = NULL;
+ return b;
+}
+
+
+gcry_mpi_t
+gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize = u->nlimbs;
+ int usign = u->sign;
+
+ if (!w)
+ w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
+ RESIZE_IF_NEEDED(w, usize);
+ wp = w->d;
+ up = u->d;
+ MPN_COPY( wp, up, usize );
+ w->nlimbs = usize;
+ w->flags = u->flags;
+ w->sign = usign;
+ return w;
+}
+
+
+gcry_mpi_t
+gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
+{
+ if (!w)
+ w = _gcry_mpi_alloc (1);
+ /* FIXME: If U is 0 we have no need to resize and thus possible
+ allocating the the limbs. */
+ RESIZE_IF_NEEDED(w, 1);
+ w->d[0] = u;
+ w->nlimbs = u? 1:0;
+ w->sign = 0;
+ w->flags = 0;
+ return w;
+}
+
+gcry_err_code_t
+_gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ unsigned long x = 0;
+
+ if (w->nlimbs > 1)
+ err = GPG_ERR_TOO_LARGE;
+ else if (w->nlimbs == 1)
+ x = w->d[0];
+ else
+ x = 0;
+
+ if (! err)
+ *u = x;
+
+ return err;
+}
+
+gcry_error_t
+gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ err = _gcry_mpi_get_ui (w, u);
+
+ return gcry_error (err);
+}
+
+gcry_mpi_t
+_gcry_mpi_alloc_set_ui( unsigned long u)
+{
+ gcry_mpi_t w = mpi_alloc(1);
+ w->d[0] = u;
+ w->nlimbs = u? 1:0;
+ w->sign = 0;
+ return w;
+}
+
+void
+gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
+{
+ struct gcry_mpi tmp;
+
+ tmp = *a; *a = *b; *b = tmp;
+}
+
+
+gcry_mpi_t
+gcry_mpi_new( unsigned int nbits )
+{
+ return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
+ / BITS_PER_MPI_LIMB );
+}
+
+
+gcry_mpi_t
+gcry_mpi_snew( unsigned int nbits )
+{
+ return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
+ / BITS_PER_MPI_LIMB );
+}
+
+void
+gcry_mpi_release( gcry_mpi_t a )
+{
+ _gcry_mpi_free( a );
+}
+
+void
+gcry_mpi_randomize( gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level )
+{
+ unsigned char *p;
+ size_t nbytes = (nbits+7)/8;
+
+ if (level == GCRY_WEAK_RANDOM)
+ {
+ p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes)
+ : gcry_xmalloc (nbytes);
+ gcry_create_nonce (p, nbytes);
+ }
+ else
+ {
+ p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level)
+ : gcry_random_bytes (nbytes, level);
+ }
+ _gcry_mpi_set_buffer( w, p, nbytes, 0 );
+ gcry_free (p);
+}
+
+
+void
+gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+{
+ switch( flag ) {
+ case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
+ case GCRYMPI_FLAG_OPAQUE:
+ default: log_bug("invalid flag value\n");
+ }
+}
+
+void
+gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+{
+ (void)a; /* Not yet used. */
+
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_SECURE:
+ case GCRYMPI_FLAG_OPAQUE:
+ default: log_bug("invalid flag value\n");
+ }
+}
+
+int
+gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+{
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_SECURE: return (a->flags & 1);
+ case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4);
+ default: log_bug("invalid flag value\n");
+ }
+ /*NOTREACHED*/
+ return 0;
+}
diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/Manifest b/grub-core/lib/libgcrypt/mpi/pa7100/Manifest
new file mode 100644
index 0000000..f075ab0
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pa7100/Manifest
@@ -0,0 +1,22 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-lshift.S
+mpih-rshift.S
+$names$ iQCVAwUAP+LmVjEAnp832S/7AQKlEQQAv2+x/d+Z0t8FwwHlxKpIKOJDr9e+Y2i8y8orcIEa3dnwU5LMOH3EzFoNSD9crc31FMokgm/X5xeLjqRTdcmGHyJJQJDPJVJyuaOm6qHJaFzzfJjrfMW66nJxfNSXIiIm4DgpP20NmumaorLCkiIZ5Z81KGAc8FiRggbRVYx+wxo==Vjh9
diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/distfiles b/grub-core/lib/libgcrypt/mpi/pa7100/distfiles
new file mode 100644
index 0000000..e1cde4d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pa7100/distfiles
@@ -0,0 +1,4 @@
+Manifest
+mpih-lshift.S
+mpih-rshift.S
+
diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S
new file mode 100644
index 0000000..8ade196
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S
@@ -0,0 +1,96 @@
+/* hppa lshift
+ * optimized for the PA7100, where it runs at 3.25 cycles/limb
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_lshift
+ .label _gcry_mpih_lshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(0,%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L$0004
+ vshd %r0,%r22,%r28 ; compute carry out limb
+ ldws,mb -4(0,%r25),%r29
+ addib,<= -5,%r24,L$rest
+ vshd %r22,%r29,%r20
+
+ .label L$loop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,> -4,%r24,L$loop
+ vshd %r22,%r29,%r20
+
+ .label L$rest
+ addib,= 4,%r24,L$end1
+ nop
+ .label L$eloop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ addib,<= -1,%r24,L$end2
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,> -1,%r24,L$eloop
+ vshd %r22,%r29,%r20
+
+ .label L$end1
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+ .label L$end2
+ stws,mb %r20,-4(0,%r26)
+ .label L$0004
+ vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+
+ .exit
+ .procend
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S
new file mode 100644
index 0000000..0624202
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S
@@ -0,0 +1,92 @@
+/* hppa rshift
+ * optimized for the PA7100, where it runs at 3.25 cycles/limb
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_rshift
+ .label _gcry_mpih_rshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L$r004
+ vshd %r22,%r0,%r28 ; compute carry out limb
+ ldws,ma 4(0,%r25),%r29
+ addib,<= -5,%r24,L$rrest
+ vshd %r29,%r22,%r20
+
+ .label L$roop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,> -4,%r24,L$roop
+ vshd %r29,%r22,%r20
+
+ .label L$rrest
+ addib,= 4,%r24,L$rend1
+ nop
+ .label L$eroop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ addib,<= -1,%r24,L$rend2
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,> -1,%r24,L$eroop
+ vshd %r29,%r22,%r20
+
+ .label L$rend1
+ stws,ma %r20,4(0,%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+ .label L$rend2
+ stws,ma %r20,4(0,%r26)
+ .label L$r004
+ vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+
+ .exit
+ .procend
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/README b/grub-core/lib/libgcrypt/mpi/pentium4/README
new file mode 100644
index 0000000..215fc7f
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/README
@@ -0,0 +1,115 @@
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+
+
+
+ INTEL PENTIUM-4 MPN SUBROUTINES
+
+
+This directory contains mpn functions optimized for Intel Pentium-4.
+
+The mmx subdirectory has routines using MMX instructions, the sse2
+subdirectory has routines using SSE2 instructions. All P4s have these, the
+separate directories are just so configure can omit that code if the
+assembler doesn't support it.
+
+
+STATUS
+
+ cycles/limb
+
+ mpn_add_n/sub_n 4 normal, 6 in-place
+
+ mpn_mul_1 4 normal, 6 in-place
+ mpn_addmul_1 6
+ mpn_submul_1 7
+
+ mpn_mul_basecase 6 cycles/crossproduct (approx)
+
+ mpn_sqr_basecase 3.5 cycles/crossproduct (approx)
+ or 7.0 cycles/triangleproduct (approx)
+
+ mpn_l/rshift 1.75
+
+
+
+The shifts ought to be able to go at 1.5 c/l, but not much effort has been
+applied to them yet.
+
+In-place operations, and all addmul, submul, mul_basecase and sqr_basecase
+calls, suffer from pipeline anomalies associated with write combining and
+movd reads and writes to the same or nearby locations. The movq
+instructions do not trigger the same hardware problems. Unfortunately,
+using movq and splitting/combining seems to require too many extra
+instructions to help. Perhaps future chip steppings will be better.
+
+
+
+NOTES
+
+The Pentium-4 pipeline "Netburst", provides for quite a number of surprises.
+Many traditional x86 instructions run very slowly, requiring use of
+alterative instructions for acceptable performance.
+
+adcl and sbbl are quite slow at 8 cycles for reg->reg. paddq of 32-bits
+within a 64-bit mmx register seems better, though the combination
+paddq/psrlq when propagating a carry is still a 4 cycle latency.
+
+incl and decl should be avoided, instead use add $1 and sub $1. Apparently
+the carry flag is not separately renamed, so incl and decl depend on all
+previous flags-setting instructions.
+
+shll and shrl have a 4 cycle latency, or 8 times the latency of the fastest
+integer instructions (addl, subl, orl, andl, and some more). shldl and
+shrdl seem to have 13 and 15 cycles latency, respectively. Bizarre.
+
+movq mmx -> mmx does have 6 cycle latency, as noted in the documentation.
+pxor/por or similar combination at 2 cycles latency can be used instead.
+The movq however executes in the float unit, thereby saving MMX execution
+resources. With the right juggling, data moves shouldn't be on a dependent
+chain.
+
+L1 is write-through, but the write-combining sounds like it does enough to
+not require explicit destination prefetching.
+
+xmm registers so far haven't found a use, but not much effort has been
+expended. A configure test for whether the operating system knows
+fxsave/fxrestor will be needed if they're used.
+
+
+
+REFERENCES
+
+Intel Pentium-4 processor manuals,
+
+ http://developer.intel.com/design/pentium4/manuals
+
+"Intel Pentium 4 Processor Optimization Reference Manual", Intel, 2001,
+order number 248966. Available on-line:
+
+ http://developer.intel.com/design/pentium4/manuals/248966.htm
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/distfiles
new file mode 100644
index 0000000..b419f85
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/distfiles
@@ -0,0 +1,3 @@
+README
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles
new file mode 100644
index 0000000..8f0ea42
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles
@@ -0,0 +1,2 @@
+mpih-lshift.S
+mpih-rshift.S
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S
new file mode 100644
index 0000000..e2dd184
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S
@@ -0,0 +1,457 @@
+/* Intel Pentium-4 mpn_lshift -- left shift.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 1.75 cycles/limb
+ * P4 Prescott: 2.0 cycles/limb
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+
+
+ pushl %ebx
+ pushl %edi
+
+
+ movl 20(%esp), %eax
+ movl 12(%esp), %edx
+
+ movl 16(%esp), %ebx
+ movl 24(%esp), %ecx
+
+ cmp $5, %eax
+ jae .Lunroll
+
+ movl -4(%ebx,%eax,4), %edi
+ decl %eax
+
+ jnz .Lsimple
+
+ shldl %cl, %edi, %eax
+
+ shll %cl, %edi
+
+ movl %edi, (%edx)
+ popl %edi
+
+ popl %ebx
+
+ ret
+
+
+
+
+
+.Lsimple:
+
+
+
+
+
+
+
+
+
+ movd (%ebx,%eax,4), %mm5
+
+ movd %ecx, %mm6
+ negl %ecx
+
+ psllq %mm6, %mm5
+ addl $32, %ecx
+
+ movd %ecx, %mm7
+ psrlq $32, %mm5
+
+
+.Lsimple_top:
+
+
+
+
+
+
+
+
+
+
+
+
+ movq -4(%ebx,%eax,4), %mm0
+ decl %eax
+
+ psrlq %mm7, %mm0
+
+
+
+ movd %mm0, 4(%edx,%eax,4)
+ jnz .Lsimple_top
+
+
+ movd (%ebx), %mm0
+
+ movd %mm5, %eax
+ psllq %mm6, %mm0
+
+ popl %edi
+ popl %ebx
+
+ movd %mm0, (%edx)
+
+ emms
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll:
+
+
+
+
+
+
+
+
+
+ movd -4(%ebx,%eax,4), %mm5
+ leal (%ebx,%eax,4), %edi
+
+ movd %ecx, %mm6
+ andl $4, %edi
+
+ psllq %mm6, %mm5
+ jz .Lstart_src_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq -8(%ebx,%eax,4), %mm0
+
+ psllq %mm6, %mm0
+ decl %eax
+
+ psrlq $32, %mm0
+
+
+
+ movd %mm0, (%edx,%eax,4)
+.Lstart_src_aligned:
+
+ movq -8(%ebx,%eax,4), %mm1
+ leal (%edx,%eax,4), %edi
+
+ andl $4, %edi
+ psrlq $32, %mm5
+
+ movq -16(%ebx,%eax,4), %mm3
+ jz .Lstart_dst_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm1, %mm0
+ addl $32, %ecx
+
+ psllq %mm6, %mm0
+
+ movd %ecx, %mm6
+ psrlq $32, %mm0
+
+
+
+ movd %mm0, -4(%edx,%eax,4)
+ subl $4, %edx
+.Lstart_dst_aligned:
+
+
+ psllq %mm6, %mm1
+ negl %ecx
+
+ addl $64, %ecx
+ movq %mm3, %mm2
+
+ movd %ecx, %mm7
+ subl $8, %eax
+
+ psrlq %mm7, %mm3
+
+ por %mm1, %mm3
+ jc .Lfinish
+
+
+
+
+ .align 8, 0x90
+.Lunroll_loop:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq 8(%ebx,%eax,4), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ movq %mm3, 24(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq (%ebx,%eax,4), %mm3
+ psllq %mm6, %mm1
+
+ movq %mm0, 16(%edx,%eax,4)
+ movq %mm3, %mm2
+
+ psrlq %mm7, %mm3
+ subl $4, %eax
+
+ por %mm1, %mm3
+ jnc .Lunroll_loop
+
+
+
+.Lfinish:
+
+
+ testb $2, %al
+
+ jz .Lfinish_no_two
+
+ movq 8(%ebx,%eax,4), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ movq %mm3, 24(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq %mm1, %mm2
+ movq %mm0, %mm3
+
+ subl $2, %eax
+.Lfinish_no_two:
+
+
+
+
+
+
+
+ testb $1, %al
+ movd %mm5, %eax
+
+ popl %edi
+ jz .Lfinish_zero
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm3, 12(%edx)
+ psllq $32, %mm0
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ por %mm2, %mm0
+ psllq %mm6, %mm1
+
+ movq %mm0, 4(%edx)
+ psrlq $32, %mm1
+
+ andl $32, %ecx
+ popl %ebx
+
+ jz .Lfinish_one_unaligned
+
+ movd %mm1, (%edx)
+.Lfinish_one_unaligned:
+
+ emms
+
+ ret
+
+
+
+
+.Lfinish_zero:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm3, 8(%edx)
+ andl $32, %ecx
+
+ psllq %mm6, %mm2
+ jz .Lfinish_zero_unaligned
+
+ movq %mm2, (%edx)
+.Lfinish_zero_unaligned:
+
+ psrlq $32, %mm2
+ popl %ebx
+
+ movd %mm5, %eax
+
+ movd %mm2, 4(%edx)
+
+ emms
+
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S
new file mode 100644
index 0000000..e3374e3
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S
@@ -0,0 +1,453 @@
+/* Intel Pentium-4 mpn_rshift -- right shift.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 1.75 cycles/limb
+ * P4 Prescott: 2.0 cycles/limb
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ pushl %ebx
+ pushl %edi
+
+
+ movl 20(%esp), %eax
+ movl 12(%esp), %edx
+
+ movl 16(%esp), %ebx
+ movl 24(%esp), %ecx
+
+ cmp $5, %eax
+ jae .Lunroll
+
+ decl %eax
+ movl (%ebx), %edi
+
+ jnz .Lsimple
+
+ shrdl %cl, %edi, %eax
+
+ shrl %cl, %edi
+
+ movl %edi, (%edx)
+ popl %edi
+
+ popl %ebx
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lsimple:
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm5
+ leal (%ebx,%eax,4), %ebx
+
+ movd %ecx, %mm6
+ leal -4(%edx,%eax,4), %edx
+
+ psllq $32, %mm5
+ negl %eax
+
+
+
+
+
+
+
+.Lsimple_top:
+
+
+
+
+
+
+
+
+
+ movq (%ebx,%eax,4), %mm0
+ incl %eax
+
+ psrlq %mm6, %mm0
+
+ movd %mm0, (%edx,%eax,4)
+ jnz .Lsimple_top
+
+
+ movd (%ebx), %mm0
+ psrlq %mm6, %mm5
+
+ psrlq %mm6, %mm0
+ popl %edi
+
+ movd %mm5, %eax
+ popl %ebx
+
+ movd %mm0, 4(%edx)
+
+ emms
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll:
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm5
+ movl $4, %edi
+
+ movd %ecx, %mm6
+ testl %edi, %ebx
+
+ psllq $32, %mm5
+ jz .Lstart_src_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq (%ebx), %mm0
+
+ psrlq %mm6, %mm0
+ addl $4, %ebx
+
+ decl %eax
+
+ movd %mm0, (%edx)
+ addl $4, %edx
+.Lstart_src_aligned:
+
+
+ movq (%ebx), %mm1
+ testl %edi, %edx
+
+ psrlq %mm6, %mm5
+ jz .Lstart_dst_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm1, %mm0
+ addl $32, %ecx
+
+ psrlq %mm6, %mm0
+
+ movd %ecx, %mm6
+
+ movd %mm0, (%edx)
+ addl $4, %edx
+.Lstart_dst_aligned:
+
+
+ movq 8(%ebx), %mm3
+ negl %ecx
+
+ movq %mm3, %mm2
+ addl $64, %ecx
+
+ movd %ecx, %mm7
+ psrlq %mm6, %mm1
+
+ leal -12(%ebx,%eax,4), %ebx
+ leal -20(%edx,%eax,4), %edx
+
+ psllq %mm7, %mm3
+ subl $7, %eax
+
+ por %mm1, %mm3
+ negl %eax
+
+ jns .Lfinish
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll_loop:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq (%ebx,%eax,4), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, -8(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq 8(%ebx,%eax,4), %mm3
+ psrlq %mm6, %mm1
+
+ movq %mm0, (%edx,%eax,4)
+ movq %mm3, %mm2
+
+ psllq %mm7, %mm3
+ addl $4, %eax
+
+ por %mm1, %mm3
+ js .Lunroll_loop
+
+
+.Lfinish:
+
+
+ testb $2, %al
+
+ jnz .Lfinish_no_two
+
+ movq (%ebx,%eax,4), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, -8(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq %mm1, %mm2
+ movq %mm0, %mm3
+
+ addl $2, %eax
+.Lfinish_no_two:
+
+
+
+
+
+
+
+ testb $1, %al
+ popl %edi
+
+ movd %mm5, %eax
+ jnz .Lfinish_zero
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movd 8(%ebx), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, (%edx)
+ por %mm2, %mm0
+
+ psrlq %mm6, %mm1
+ andl $32, %ecx
+
+ popl %ebx
+ jz .Lfinish_one_unaligned
+
+
+ movd %mm1, 16(%edx)
+.Lfinish_one_unaligned:
+
+ movq %mm0, 8(%edx)
+
+ emms
+
+ ret
+
+
+
+
+.Lfinish_zero:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm3, 4(%edx)
+ psrlq %mm6, %mm2
+
+ movd %mm2, 12(%edx)
+ andl $32, %ecx
+
+ popl %ebx
+ jz .Lfinish_zero_unaligned
+
+ movq %mm2, 12(%edx)
+.Lfinish_zero_unaligned:
+
+ emms
+
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles
new file mode 100644
index 0000000..7252cd7
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles
@@ -0,0 +1,5 @@
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-sub1.S
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S
new file mode 100644
index 0000000..55ed663
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S
@@ -0,0 +1,91 @@
+/* Intel Pentium-4 mpn_add_n -- mpn addition.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+ /*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2
+ * 6.0 cycles/limb if dst==src1 or dst==src2
+ * P4 Prescott: >= 5 cycles/limb
+ *
+ * The 4 c/l achieved here isn't particularly good, but is better than 9 c/l
+ * for a basic adc loop.
+ */
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+
+ pxor %mm0, %mm0
+
+ movl 8(%esp), %eax /* s1_ptr */
+ movl %ebx, 8(%esp) /* re-use parameter space */
+ movl 12(%esp), %ebx /* res_ptr */
+ movl 4(%esp), %edx /* s2_ptr */
+ movl 16(%esp), %ecx /* size */
+
+ leal (%eax,%ecx,4), %eax /* src1 end */
+ leal (%ebx,%ecx,4), %ebx /* src2 end */
+ leal (%edx,%ecx,4), %edx /* dst end */
+ negl %ecx /* -size */
+
+Ltop:
+/*
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry bit
+*/
+
+ movd (%eax,%ecx,4), %mm1
+ movd (%ebx,%ecx,4), %mm2
+ paddq %mm2, %mm1
+
+ paddq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $32, %mm0
+
+ addl $1, %ecx
+ jnz Ltop
+
+
+ movd %mm0, %eax
+ movl 8(%esp), %ebx /* restore saved EBX */
+ emms
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S
new file mode 100644
index 0000000..a0c98fb
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S
@@ -0,0 +1,96 @@
+/* Intel Pentium-4 mpn_mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * src != dst src == dst
+ * P6 model 9 (Banias) ?.?
+ * P6 model 13 (Dothan) 4.75 4.75
+ * P4 model 0 (Willamette) 4.0 6.0
+ * P4 model 1 (?) 4.0 6.0
+ * P4 model 2 (Northwood) 4.0 6.0
+ * P4 model 3 (Prescott) ?.? ?.?
+ * P4 model 4 (Nocona) ?.? ?.?
+ * Unfortunately when src==dst the write-combining described in
+ * pentium4/README takes us up to 6 c/l.
+ *
+ */
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:);
+
+ pxor %mm0, %mm0
+
+.Lstart_1c:
+ movl 8(%esp), %eax
+ movd 16(%esp), %mm7
+ movl 4(%esp), %edx
+ movl 12(%esp), %ecx
+
+.Ltop:
+
+/*
+ C eax src, incrementing
+ C ebx
+ C ecx counter, size iterations
+ C edx dst, incrementing
+ C
+ C mm0 carry limb
+ C mm7 multiplier
+*/
+
+ movd (%eax), %mm1
+ addl $4, %eax
+ pmuludq %mm7, %mm1
+
+ paddq %mm1, %mm0
+ movd %mm0, (%edx)
+ addl $4, %edx
+
+ psrlq $32, %mm0
+
+ subl $1, %ecx
+ jnz .Ltop
+
+
+ movd %mm0, %eax
+ emms
+ ret
+
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S
new file mode 100644
index 0000000..f975adf
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S
@@ -0,0 +1,136 @@
+/* Intel Pentium-4 mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * P3 model 9 (Banias) ?.?
+ * P3 model 13 (Dothan) 5.8
+ * P4 model 0 (Willamette) 5.5
+ * P4 model 1 (?) 5.5
+ * P4 model 2 (Northwood) 5.5
+ * P4 model 3 (Prescott) 6.0
+ * P4 model 4 (Nocona)
+ *
+ * Only the carry limb propagation is on the dependent chain, but some other
+ * Pentium4 pipeline magic brings down performance to 6 cycles/l from the
+ * ideal 4 cycles/l.
+ */
+
+
+ TEXT
+ ALIGN (4)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ pxor %mm4, %mm4
+.Lstart_1c:
+ movl 8(%esp), %eax
+ movl 12(%esp), %ecx
+ movl 4(%esp), %edx
+ movd 16(%esp), %mm7
+
+/*
+ C eax src, incrementing ; 5B
+ C ecx loop counter, decrementing
+ C edx dst, incrementing
+ C
+ C mm4 carry, low 32-bits
+ C mm7 multiplier
+*/
+
+ movd (%eax), %mm2
+ pmuludq %mm7, %mm2
+
+ shrl $1, %ecx
+ jnc .Leven
+
+ leal 4(%eax), %eax
+ movd (%edx), %mm1
+ paddq %mm2, %mm1
+ paddq %mm1, %mm4
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+
+ testl %ecx, %ecx
+ jz .Lrtn
+ leal 4(%edx), %edx
+
+ movd (%eax), %mm2
+ pmuludq %mm7, %mm2
+.Leven:
+ movd 4(%eax), %mm0
+ movd (%edx), %mm1
+ pmuludq %mm7, %mm0
+
+ subl $1, %ecx
+ jz .Lend
+.Lloop:
+ paddq %mm2, %mm1
+ movd 8(%eax), %mm2
+ paddq %mm1, %mm4
+ movd 4(%edx), %mm3
+ pmuludq %mm7, %mm2
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+
+ paddq %mm0, %mm3
+ movd 12(%eax), %mm0
+ paddq %mm3, %mm4
+ movd 8(%edx), %mm1
+ pmuludq %mm7, %mm0
+ movd %mm4, 4(%edx)
+ psrlq $32, %mm4
+
+ leal 8(%eax), %eax
+ leal 8(%edx), %edx
+ subl $1, %ecx
+ jnz .Lloop
+.Lend:
+ paddq %mm2, %mm1
+ paddq %mm1, %mm4
+ movd 4(%edx), %mm3
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+ paddq %mm0, %mm3
+ paddq %mm3, %mm4
+ movd %mm4, 4(%edx)
+ psrlq $32, %mm4
+.Lrtn:
+ movd %mm4, %eax
+ emms
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S
new file mode 100644
index 0000000..ebcd2a6
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S
@@ -0,0 +1,127 @@
+/* Intel Pentium-4 mpn_submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * P4: 7 cycles/limb, unstable timing, at least on early Pentium4 silicon
+ * (stepping 10).
+ *
+ * This code is not particularly good at 7 c/l. The dependent chain is only
+ * 4 c/l and there's only 4 MMX unit instructions, so it's not clear why that
+ * speed isn't achieved.
+ *
+ * The arrangements made here to get a two instruction dependent chain are
+ * slightly subtle. In the loop the carry (or borrow rather) is a negative
+ * so that a paddq can be used to give a low limb ready to store, and a high
+ * limb ready to become the new carry after a psrlq.
+ *
+ * If the carry was a simple twos complement negative then the psrlq shift
+ * would need to bring in 0 bits or 1 bits according to whether the high was
+ * zero or non-zero, since a non-zero value would represent a negative
+ * needing sign extension. That wouldn't be particularly easy to arrange and
+ * certainly would add an instruction to the dependent chain, so instead an
+ * offset is applied so that the high limb will be 0xFFFFFFFF+c. With c in
+ * the range -0xFFFFFFFF to 0, the value 0xFFFFFFFF+c is in the range 0 to
+ * 0xFFFFFFFF and is therefore always positive and can always have 0 bits
+ * shifted in, which is what psrlq does.
+ *
+ * The extra 0xFFFFFFFF must be subtracted before c is used, but that can be
+ * done off the dependent chain. The total adjustment then is to add
+ * 0xFFFFFFFF00000000 to offset the new carry, and subtract
+ * 0x00000000FFFFFFFF to remove the offset from the current carry, for a net
+ * add of 0xFFFFFFFE00000001. In the code this is applied to the destination
+ * limb when fetched.
+ *
+ * It's also possible to view the 0xFFFFFFFF adjustment as a ones-complement
+ * negative, which is how it's undone for the return value, but that doesn't
+ * seem as clear.
+*/
+
+ TEXT
+ ALIGN (4)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ pxor %mm1, %mm1
+
+.Lstart_1c:
+ movl 8(%esp), %eax
+ pcmpeqd %mm0, %mm0
+
+ movd 16(%esp), %mm7
+ pcmpeqd %mm6, %mm6
+
+ movl 4(%esp), %edx
+ psrlq $32, %mm0
+
+ movl 12(%esp), %ecx
+ psllq $32, %mm6
+
+ psubq %mm0, %mm6
+
+ psubq %mm1, %mm0
+
+/*
+ C eax src, incrementing
+ C ebx
+ C ecx loop counter, decrementing
+ C edx dst, incrementing
+ C
+ C mm0 0xFFFFFFFF - borrow
+ C mm6 0xFFFFFFFE00000001
+ C mm7 multiplier
+*/
+
+.Lloop:
+ movd (%eax), %mm1
+ leal 4(%eax), %eax
+ movd (%edx), %mm2
+ paddq %mm6, %mm2
+ pmuludq %mm7, %mm1
+ psubq %mm1, %mm2
+ paddq %mm2, %mm0
+ subl $1, %ecx
+ movd %mm0, (%edx)
+ psrlq $32, %mm0
+ leal 4(%edx), %edx
+ jnz .Lloop
+
+ movd %mm0, %eax
+ notl %eax
+ emms
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S
new file mode 100644
index 0000000..33900c7
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S
@@ -0,0 +1,112 @@
+/* Intel Pentium-4 mpn_sub_n -- mpn subtraction.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2
+ * 6.0 cycles/limb if dst==src1 or dst==src2
+ * P4 Prescott: >= 5 cycles/limb
+ *
+ * The main loop code is 2x unrolled so that the carry bit can alternate
+ * between mm0 and mm1.
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+
+ pxor %mm0, %mm0
+.Lstart_nc:
+ movl 8(%esp), %eax
+ movl %ebx, 8(%esp)
+ movl 12(%esp), %ebx
+ movl 4(%esp), %edx
+ movl 16(%esp), %ecx
+
+ leal (%eax,%ecx,4), %eax
+ leal (%ebx,%ecx,4), %ebx
+ leal (%edx,%ecx,4), %edx
+ negl %ecx
+
+.Ltop:
+/*
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry bit
+*/
+
+ movd (%eax,%ecx,4), %mm1
+ movd (%ebx,%ecx,4), %mm2
+ psubq %mm2, %mm1
+
+ psubq %mm0, %mm1
+ movd %mm1, (%edx,%ecx,4)
+
+ psrlq $63, %mm1
+
+ addl $1, %ecx
+ jz .Ldone_mm1
+
+ movd (%eax,%ecx,4), %mm0
+ movd (%ebx,%ecx,4), %mm2
+ psubq %mm2, %mm0
+
+ psubq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $63, %mm0
+
+ addl $1, %ecx
+ jnz .Ltop
+
+
+ movd %mm0, %eax
+ movl 8(%esp), %ebx
+ emms
+ ret
+
+
+
+.Ldone_mm1:
+ movd %mm1, %eax
+ movl 8(%esp), %ebx
+ emms
+ ret
diff --git a/grub-core/lib/libgcrypt/mpi/power/Manifest b/grub-core/lib/libgcrypt/mpi/power/Manifest
new file mode 100644
index 0000000..c60fc23
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/Manifest
@@ -0,0 +1,27 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-lshift.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-rshift.S
+mpih-sub1.S
+$names$ iQCVAwUAP+LmXTEAnp832S/7AQJ+ngP/XYr5Fvl/8WGVHcIKaehxvnKcSD2ILTWZNGubgnWp8ebIxVijjQCxYneTTy+zO0sNaB002neyscyiwaJj/JQIwZXfr06uGweIqlSpwpj9ndkoJc8E4/FZu+5NTO+E3RaBDAD+Tpo+MTfbC1s18p5i+an93VrSTgNck5PPYQrUcPA==sl3t
diff --git a/grub-core/lib/libgcrypt/mpi/power/distfiles b/grub-core/lib/libgcrypt/mpi/power/distfiles
new file mode 100644
index 0000000..e1bc008
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/distfiles
@@ -0,0 +1,8 @@
+Manifest
+mpih-add1.S
+mpih-lshift.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-rshift.S
+mpih-sub1.S
diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S
new file mode 100644
index 0000000..876b56c
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S
@@ -0,0 +1,87 @@
+/* IBM POWER add_n -- Add two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1999,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# s2_ptr r5
+# size r6
+ */
+
+ .toc
+ .extern _gcry_mpih_add_n[DS]
+ .extern ._gcry_mpih_add_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_add_n
+ .globl ._gcry_mpih_add_n
+ .csect _gcry_mpih_add_n[DS]
+_gcry_mpih_add_n:
+ .long ._gcry_mpih_add_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_add_n:
+ andil. 10,6,1 # odd or even number of limbs?
+ l 8,0(4) # load least significant s1 limb
+ l 0,0(5) # load least significant s2 limb
+ cal 3,-4(3) # offset res_ptr, it's updated before it's used
+ sri 10,6,1 # count for unrolled loop
+ a 7,0,8 # add least significant limbs, set cy
+ mtctr 10 # copy count into CTR
+ beq 0,Leven # branch if even # of limbs (# of limbs >= 2)
+
+# We have an odd # of limbs. Add the first limbs separately.
+ cmpi 1,10,0 # is count for unrolled loop zero?
+ bne 1,L1 # branch if not
+ st 7,4(3)
+ aze 3,10 # use the fact that r10 is zero...
+ br # return
+
+# We added least significant limbs. Now reload the next limbs to enter loop.
+L1: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ stu 7,4(3)
+ ae 7,0,8 # add limbs, set cy
+Leven: lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ bdz Lend # If done, skip loop
+
+Loop: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ ae 11,9,10 # add previous limbs with cy, set cy
+ stu 7,4(3) #
+ lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ ae 7,0,8 # add previous limbs with cy, set cy
+ stu 11,4(3) #
+ bdn Loop # decrement CTR and loop back
+
+Lend: ae 11,9,10 # add limbs with cy, set cy
+ st 7,4(3) #
+ st 11,8(3) #
+ lil 3,0 # load cy into ...
+ aze 3,3 # ... return value register
+ br
+
diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S
new file mode 100644
index 0000000..d9e42da
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S
@@ -0,0 +1,64 @@
+/* IBM POWER lshift
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s_ptr r4
+# size r5
+# cnt r6
+ */
+
+ .toc
+ .extern _gcry_mpih_lshift[DS]
+ .extern ._gcry_mpih_lshift
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_lshift
+ .globl ._gcry_mpih_lshift
+ .csect _gcry_mpih_lshift[DS]
+_gcry_mpih_lshift:
+ .long ._gcry_mpih_lshift, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_lshift:
+ sli 0,5,2
+ cax 9,3,0
+ cax 4,4,0
+ sfi 8,6,32
+ mtctr 5 # put limb count in CTR loop register
+ lu 0,-4(4) # read most significant limb
+ sre 3,0,8 # compute carry out limb, and init MQ register
+ bdz Lend2 # if just one limb, skip loop
+ lu 0,-4(4) # read 2:nd most significant limb
+ sreq 7,0,8 # compute most significant limb of result
+ bdz Lend # if just two limb, skip loop
+Loop: lu 0,-4(4) # load next lower limb
+ stu 7,-4(9) # store previous result during read latency
+ sreq 7,0,8 # compute result limb
+ bdn Loop # loop back until CTR is zero
+Lend: stu 7,-4(9) # store 2:nd least significant limb
+Lend2: sle 7,0,6 # compute least significant limb
+ st 7,-4(9) # store it
+ br
+
diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S
new file mode 100644
index 0000000..35034fa
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S
@@ -0,0 +1,115 @@
+/* IBM POWER mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_mul_1[PR]
+ .align 2
+ .globl _gcry_mpih_mul_1
+ .globl ._gcry_mpih_mul_1
+ .csect _gcry_mpih_mul_1[DS]
+_gcry_mpih_mul_1:
+ .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_mul_1[PR]
+._gcry_mpih_mul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 8
+ ai 0,0,0 # reset carry
+ cax 9,9,7
+ blt Lneg
+Lpos: bdz Lend
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 8,0,9
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 8,0,10
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ cax 10,10,0 # adjust high limb for negative s2_limb
+ mfmq 0
+ ae 8,0,9
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ cax 9,9,0 # adjust high limb for negative s2_limb
+ mfmq 0
+ ae 8,0,10
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S
new file mode 100644
index 0000000..d056e8f
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S
@@ -0,0 +1,130 @@
+/* IBM POWER addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_addmul_1[PR]
+ .align 2
+ .globl _gcry_mpih_addmul_1
+ .globl ._gcry_mpih_addmul_1
+ .csect _gcry_mpih_addmul_1[DS]
+_gcry_mpih_addmul_1:
+ .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_addmul_1[PR]
+._gcry_mpih_addmul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 8
+ cax 9,9,7
+ l 7,4(3)
+ a 8,8,7 # add res_limb
+ blt Lneg
+Lpos: bdz Lend
+
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 8,0,9 # low limb + old_cy_limb + old cy
+ l 7,4(3)
+ aze 10,10 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 8,0,10
+ l 7,4(3)
+ aze 9,9
+ a 8,8,7
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 7
+ ae 8,7,9
+ l 7,4(3)
+ ae 10,10,0 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 7
+ ae 8,7,10
+ l 7,4(3)
+ ae 9,9,0 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S
new file mode 100644
index 0000000..8bc317b
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S
@@ -0,0 +1,135 @@
+/* IBM POWER submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*
+
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_submul_1[PR]
+ .align 2
+ .globl _gcry_mpih_submul_1
+ .globl ._gcry_mpih_submul_1
+ .csect _gcry_mpih_submul_1[DS]
+_gcry_mpih_submul_1:
+ .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_submul_1[PR]
+._gcry_mpih_submul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 11
+ cax 9,9,7
+ l 7,4(3)
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ blt Lneg
+Lpos: bdz Lend
+
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 11,0,9 # low limb + old_cy_limb + old cy
+ l 7,4(3)
+ aze 10,10 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 11,0,10
+ l 7,4(3)
+ aze 9,9
+ sf 8,11,7
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 7
+ ae 11,7,9
+ l 7,4(3)
+ ae 10,10,0 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 7
+ ae 11,7,10
+ l 7,4(3)
+ ae 9,9,0 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S
new file mode 100644
index 0000000..f131a86
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S
@@ -0,0 +1,64 @@
+/* IBM POWER rshift
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s_ptr r4
+# size r5
+# cnt r6
+*/
+
+ .toc
+ .extern _gcry_mpih_rshift[DS]
+ .extern ._gcry_mpih_rshift
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_rshift
+ .globl ._gcry_mpih_rshift
+ .csect _gcry_mpih_rshift[DS]
+_gcry_mpih_rshift:
+ .long ._gcry_mpih_rshift, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_rshift:
+ sfi 8,6,32
+ mtctr 5 # put limb count in CTR loop register
+ l 0,0(4) # read least significant limb
+ ai 9,3,-4 # adjust res_ptr since it's offset in the stu:s
+ sle 3,0,8 # compute carry limb, and init MQ register
+ bdz Lend2 # if just one limb, skip loop
+ lu 0,4(4) # read 2:nd least significant limb
+ sleq 7,0,8 # compute least significant limb of result
+ bdz Lend # if just two limb, skip loop
+Loop: lu 0,4(4) # load next higher limb
+ stu 7,4(9) # store previous result during read latency
+ sleq 7,0,8 # compute result limb
+ bdn Loop # loop back until CTR is zero
+Lend: stu 7,4(9) # store 2:nd most significant limb
+Lend2: sre 7,0,6 # compute most significant limb
+ st 7,4(9) # store it
+ br
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S
new file mode 100644
index 0000000..02748fc
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S
@@ -0,0 +1,88 @@
+/* IBM POWER sub_n -- Subtract two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1996, 1999,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# s2_ptr r5
+# size r6
+ */
+
+ .toc
+ .extern _gcry_mpih_sub_n[DS]
+ .extern ._gcry_mpih_sub_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .globl ._gcry_mpih_sub_n
+ .csect _gcry_mpih_sub_n[DS]
+_gcry_mpih_sub_n:
+ .long ._gcry_mpih_sub_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_sub_n:
+ andil. 10,6,1 # odd or even number of limbs?
+ l 8,0(4) # load least significant s1 limb
+ l 0,0(5) # load least significant s2 limb
+ cal 3,-4(3) # offset res_ptr, it's updated before it's used
+ sri 10,6,1 # count for unrolled loop
+ sf 7,0,8 # subtract least significant limbs, set cy
+ mtctr 10 # copy count into CTR
+ beq 0,Leven # branch if even # of limbs (# of limbs >= 2)
+
+# We have an odd # of limbs. Add the first limbs separately.
+ cmpi 1,10,0 # is count for unrolled loop zero?
+ bne 1,L1 # branch if not
+ st 7,4(3)
+ sfe 3,0,0 # load !cy into ...
+ sfi 3,3,0 # ... return value register
+ br # return
+
+# We added least significant limbs. Now reload the next limbs to enter loop.
+L1: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ stu 7,4(3)
+ sfe 7,0,8 # subtract limbs, set cy
+Leven: lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ bdz Lend # If done, skip loop
+
+Loop: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ sfe 11,10,9 # subtract previous limbs with cy, set cy
+ stu 7,4(3) #
+ lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ sfe 7,0,8 # subtract previous limbs with cy, set cy
+ stu 11,4(3) #
+ bdn Loop # decrement CTR and loop back
+
+Lend: sfe 11,10,9 # subtract limbs with cy, set cy
+ st 7,4(3) #
+ st 11,8(3) #
+ sfe 3,0,0 # load !cy into ...
+ sfi 3,3,0 # ... return value register
+ br
+
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest b/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest
new file mode 100644
index 0000000..26ab6ea
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest
@@ -0,0 +1,28 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+syntax.h
+$names$ iQCVAwUAP+LmYzEAnp832S/7AQI/cQP+Mcg9rF/c/bJTY48PE1/ARt7vCMtpIlv9alZSSSrU3WHzCtv9nVczFmwHU3DdKFawigY2DljQcK92dZ5ZlOfpFNMz4PKlVMWaKDk+jKlqm2dxvlHuqEvXPpjFAE2gHrhq5qLXS5ZHeMLJIEK84GYC6fjfLUMdZU3altXTUBvoXhA==Yax+
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles b/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles
new file mode 100644
index 0000000..a086614
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles
@@ -0,0 +1,10 @@
+Manifest
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+syntax.h
+
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S
new file mode 100644
index 0000000..1661f5e
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S
@@ -0,0 +1,136 @@
+/* PowerPC-32 add_n -- Add two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_ptr_t s2_ptr, (r5)
+ * mpi_size_t size) (r6)
+ */
+
+ .toc
+ .extern _gcry_mpih_add_n[DS]
+ .extern ._gcry_mpih_add_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_add_n
+ .globl ._gcry_mpih_add_n
+ .csect _gcry_mpih_add_n[DS]
+_gcry_mpih_add_n:
+ .long ._gcry_mpih_add_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_add_n:
+ mtctr 6 # copy size into CTR
+ lwz 8,0(4) # load least significant s1 limb
+ lwz 0,0(5) # load least significant s2 limb
+ addi 3,3,-4 # offset res_ptr, it is updated before used
+ addc 7,0,8 # add least significant limbs, set cy
+ bdz Lend # If done, skip loop
+Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr
+ lwzu 0,4(5) # load s2 limb and update s2_ptr
+ stwu 7,4(3) # store previous limb in load latency slot
+ adde 7,0,8 # add new limbs with cy, set cy
+ bdnz Loop # decrement CTR and loop back
+Lend: stw 7,4(3) # store ultimate result limb
+ li 3,0 # load cy into ...
+ addze 3,3 # ... return value register
+ blr
+
+#else
+/* Add two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN(_gcry_mpih_add_n,3,0)
+/* Set up for loop below. */
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ li %r10,0
+ mtctr %r7
+ bt 31,2f
+
+/* Clear the carry. */
+ addic %r0,%r0,0
+/* Adjust pointers for loop. */
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ addc %r6,%r6,%r7
+ stw %r6,0(%r3)
+ beq 1f
+
+/* The loop. */
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). */
+0: lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ adde %r8,%r9,%r8
+ stw %r8,4(%r3)
+ adde %r6,%r6,%r7
+ stwu %r6,8(%r3)
+ bdnz 0b
+/* Return the carry. */
+1: addze %r3,%r10
+ blr
+END(_gcry_mpih_add_n)
+#endif
+
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S
new file mode 100644
index 0000000..6231095
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S
@@ -0,0 +1,198 @@
+/* PowerPC-32 lshift
+ *
+ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (r3)
+ * mpi_ptr_t up, (r4)
+ * mpi_size_t usize, (r5)
+ * unsigned cnt) (r6)
+ */
+
+ .toc
+.csect .text[PR]
+ .align 2
+ .globl _gcry_mpih_lshift
+ .globl ._gcry_mpih_lshift
+ .csect _gcry_mpih_lshift[DS]
+_gcry_mpih_lshift:
+ .long ._gcry_mpih_lshift, TOC[tc0], 0
+ .csect .text[PR]
+._gcry_mpih_lshift:
+ mtctr 5 # copy size into CTR
+ slwi 0,5,2
+ add 7,3,0 # make r7 point at end of res
+ add 4,4,0 # make r4 point at end of s1
+ subfic 8,6,32
+ lwzu 11,-4(4) # load first s1 limb
+ srw 3,11,8 # compute function return value
+ bdz Lend1
+
+Loop: lwzu 10,-4(4)
+ slw 9,11,6
+ srw 12,10,8
+ or 9,9,12
+ stwu 9,-4(7)
+ bdz Lend2
+ lwzu 11,-4(4)
+ slw 9,10,6
+ srw 12,11,8
+ or 9,9,12
+ stwu 9,-4(7)
+ bdnz Loop
+
+Lend1: slw 0,11,6
+ stw 0,-4(7)
+ blr
+
+Lend2: slw 0,10,6
+ stw 0,-4(7)
+ blr
+
+#else
+/* Shift a limb left, low level routine.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+ unsigned int cnt) */
+
+EALIGN(_gcry_mpih_lshift,3,0)
+ mtctr %r5 # copy size into CTR
+ cmplwi %cr0,%r5,16 # is size < 16
+ slwi %r0,%r5,2
+ add %r7,%r3,%r0 # make r7 point at end of res
+ add %r4,%r4,%r0 # make r4 point at end of s1
+ lwzu %r11,-4(%r4) # load first s1 limb
+ subfic %r8,%r6,32
+ srw %r3,%r11,%r8 # compute function return value
+ bge %cr0,L(big) # branch if size >= 16
+
+ bdz L(end1)
+
+0: lwzu %r10,-4(%r4)
+ slw %r9,%r11,%r6
+ srw %r12,%r10,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdz L(end2)
+ lwzu %r11,-4(%r4)
+ slw %r9,%r10,%r6
+ srw %r12,%r11,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdnz 0b
+
+L(end1):slw %r0,%r11,%r6
+ stw %r0,-4(%r7)
+ blr
+
+
+/* Guaranteed not to succeed. */
+L(boom): tweq %r0,%r0
+
+/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
+ of size 4*12 bytes. We have to do this (or something) to make this PIC. */
+L(big): mflr %r9
+ bltl- %cr0,L(boom) # Never taken, only used to set LR.
+ slwi %r10,%r6,4
+ mflr %r12
+ add %r10,%r12,%r10
+ slwi %r8,%r6,5
+ add %r10,%r8,%r10
+ mtctr %r10
+ addi %r5,%r5,-1
+ mtlr %r9
+ bctr
+
+L(end2):slw %r0,%r10,%r6
+ stw %r0,-4(%r7)
+ blr
+
+#define DO_LSHIFT(n) \
+ mtctr %r5; \
+0: lwzu %r10,-4(%r4); \
+ slwi %r9,%r11,n; \
+ inslwi %r9,%r10,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdz- L(end2); \
+ lwzu %r11,-4(%r4); \
+ slwi %r9,%r10,n; \
+ inslwi %r9,%r11,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdnz 0b; \
+ b L(end1)
+
+ DO_LSHIFT(1)
+ DO_LSHIFT(2)
+ DO_LSHIFT(3)
+ DO_LSHIFT(4)
+ DO_LSHIFT(5)
+ DO_LSHIFT(6)
+ DO_LSHIFT(7)
+ DO_LSHIFT(8)
+ DO_LSHIFT(9)
+ DO_LSHIFT(10)
+ DO_LSHIFT(11)
+ DO_LSHIFT(12)
+ DO_LSHIFT(13)
+ DO_LSHIFT(14)
+ DO_LSHIFT(15)
+ DO_LSHIFT(16)
+ DO_LSHIFT(17)
+ DO_LSHIFT(18)
+ DO_LSHIFT(19)
+ DO_LSHIFT(20)
+ DO_LSHIFT(21)
+ DO_LSHIFT(22)
+ DO_LSHIFT(23)
+ DO_LSHIFT(24)
+ DO_LSHIFT(25)
+ DO_LSHIFT(26)
+ DO_LSHIFT(27)
+ DO_LSHIFT(28)
+ DO_LSHIFT(29)
+ DO_LSHIFT(30)
+ DO_LSHIFT(31)
+
+END(_gcry_mpih_lshift)
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S
new file mode 100644
index 0000000..bd418f7
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S
@@ -0,0 +1,120 @@
+/* PowerPC-32 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995,
+ * 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+ .toc
+ .csect ._gcry_mpih_mul_1[PR]
+ .align 2
+ .globl _gcry_mpih_mul_1
+ .globl ._gcry_mpih_mul_1
+ .csect _gcry_mpih_mul_1[DS]
+_gcry_mpih_mul_1:
+ .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_mul_1[PR]
+._gcry_mpih_mul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ addi 3,3,-4 # adjust res_ptr
+ addic 5,5,0 # clear cy with dummy insn
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 7,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ bdnz Loop
+
+Lend: stw 7,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate s1*s2 and put result in res_ptr; return carry. */
+
+ENTRY(_gcry_mpih_mul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ addi %r3,%r3,-4 # adjust res_ptr
+ addic %r5,%r5,0 # clear cy with dummy insn
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r7,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ bdnz 0b
+
+1: stw %r7,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_mul_1)
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S
new file mode 100644
index 0000000..1d97b81
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S
@@ -0,0 +1,127 @@
+/* PowerPC-32 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+
+ .toc
+ .csect ._gcry_mpih_addmul_1[PR]
+ .align 2
+ .globl _gcry_mpih_addmul_1
+ .globl ._gcry_mpih_addmul_1
+ .csect _gcry_mpih_addmul_1[DS]
+_gcry_mpih_addmul_1:
+ .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_addmul_1[PR]
+._gcry_mpih_addmul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ lwz 9,0(3)
+ addc 8,7,9
+ addi 3,3,-4
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 8,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ lwz 9,4(3)
+ addze 10,10
+ addc 8,7,9
+ bdnz Loop
+
+Lend: stw 8,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res+s1*s2 and put result back in res; return carry. */
+ENTRY(_gcry_mpih_addmul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ addc %r8,%r7,%r9
+ addi %r3,%r3,-4 /* adjust res_ptr */
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ addc %r8,%r7,%r9
+ bdnz 0b
+
+1: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_addmul_1)
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S
new file mode 100644
index 0000000..c410dbb
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S
@@ -0,0 +1,130 @@
+/* PowerPC-32 submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+ .toc
+ .csect ._gcry_mpih_submul_1[PR]
+ .align 2
+ .globl _gcry_mpih_submul_1
+ .globl ._gcry_mpih_submul_1
+ .csect _gcry_mpih_submul_1[DS]
+_gcry_mpih_submul_1:
+ .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_submul_1[PR]
+._gcry_mpih_submul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ lwz 9,0(3)
+ subfc 8,7,9
+ addc 7,7,8 # invert cy (r7 is junk)
+ addi 3,3,-4
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 8,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ lwz 9,4(3)
+ addze 10,10
+ subfc 8,7,9
+ addc 7,7,8 # invert cy (r7 is junk)
+ bdnz Loop
+
+Lend: stw 8,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res-s1*s2 and put result back in res; return carry. */
+
+ENTRY(_gcry_mpih_submul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ addi %r3,%r3,-4 # adjust res_ptr
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ bdnz 0b
+
+1: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_submul_1)
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S
new file mode 100644
index 0000000..98349ed
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S
@@ -0,0 +1,131 @@
+/* PowerPC-32 rshift
+ *
+ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (r3)
+ * mpi_ptr_t up, (r4)
+ * mpi_size_t usize, (r5)
+ * unsigned cnt) (r6)
+ */
+
+ .toc
+.csect .text[PR]
+ .align 2
+ .globl _gcry_mpih_rshift
+ .globl ._gcry_mpih_rshift
+ .csect _gcry_mpih_rshift[DS]
+_gcry_mpih_rshift:
+ .long ._gcry_mpih_rshift, TOC[tc0], 0
+ .csect .text[PR]
+._gcry_mpih_rshift:
+ mtctr 5 # copy size into CTR
+ addi 7,3,-4 # move adjusted res_ptr to free return reg
+ subfic 8,6,32
+ lwz 11,0(4) # load first s1 limb
+ slw 3,11,8 # compute function return value
+ bdz Lend1
+
+Loop: lwzu 10,4(4)
+ srw 9,11,6
+ slw 12,10,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdz Lend2
+ lwzu 11,4(4)
+ srw 9,10,6
+ slw 12,11,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdnz Loop
+
+Lend1: srw 0,11,6
+ stw 0,4(7)
+ blr
+
+Lend2: srw 0,10,6
+ stw 0,4(7)
+ blr
+
+#else
+/* Shift a limb right, low level routine.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+/* INPUT PARAMETERS
+ res_ptr r3
+ s1_ptr r4
+ size r5
+ cnt r6 */
+
+ENTRY(_gcry_mpih_rshift)
+ mtctr 5 # copy size into CTR
+ addi 7,3,-4 # move adjusted res_ptr to free return reg
+ subfic 8,6,32
+ lwz 11,0(4) # load first s1 limb
+ slw 3,11,8 # compute function return value
+ bdz 1f
+
+0: lwzu 10,4(4)
+ srw 9,11,6
+ slw 12,10,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdz 2f
+ lwzu 11,4(4)
+ srw 9,10,6
+ slw 12,11,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdnz 0b
+
+1: srw 0,11,6
+ stw 0,4(7)
+ blr
+
+2: srw 0,10,6
+ stw 0,4(7)
+ blr
+END(_gcry_mpih_rshift)
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S
new file mode 100644
index 0000000..d612ea8
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S
@@ -0,0 +1,133 @@
+/* PowerPC-32 sub_n -- Subtract two limb vectors of the same length > 0
+ * and store difference in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_ptr_t s2_ptr, (r5)
+ * mpi_size_t size) (r6)
+ */
+
+ .toc
+ .extern _gcry_mpih_sub_n[DS]
+ .extern ._gcry_mpih_sub_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .globl ._gcry_mpih_sub_n
+ .csect _gcry_mpih_sub_n[DS]
+_gcry_mpih_sub_n:
+ .long ._gcry_mpih_sub_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_sub_n:
+ mtctr 6 # copy size into CTR
+ lwz 8,0(4) # load least significant s1 limb
+ lwz 0,0(5) # load least significant s2 limb
+ addi 3,3,-4 # offset res_ptr, it is updated before used
+ subfc 7,0,8 # add least significant limbs, set cy
+ bdz Lend # If done, skip loop
+Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr
+ lwzu 0,4(5) # load s2 limb and update s2_ptr
+ stwu 7,4(3) # store previous limb in load latency slot
+ subfe 7,0,8 # add new limbs with cy, set cy
+ bdnz Loop # decrement CTR and loop back
+Lend: stw 7,4(3) # store ultimate result limb
+ subfe 3,0,0 # load !cy into ...
+ subfic 3,3,0 # ... return value register
+ blr
+
+#else
+/* Subtract two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN(_gcry_mpih_sub_n,3,1)
+/* Set up for loop below. */
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ mtctr %r7
+ bt 31,2f
+
+/* Set the carry (clear the borrow). */
+ subfc %r0,%r0,%r0
+/* Adjust pointers for loop. */
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ subfc %r6,%r7,%r6
+ stw %r6,0(%r3)
+ beq 1f
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). This turns
+ out to be important. */
+0:
+ lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ subfe %r8,%r8,%r9
+ stw %r8,4(%r3)
+ subfe %r6,%r7,%r6
+ stwu %r6,8(%r3)
+ bdnz 0b
+/* Return the borrow. */
+1: subfe %r3,%r3,%r3
+ neg %r3,%r3
+ blr
+END(_gcry_mpih_sub_n)
+#endif
diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h b/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h
new file mode 100644
index 0000000..5d4af9f
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h
@@ -0,0 +1,75 @@
+/* gmp2-2.0.2-ppc/mpn/powerpc-linux/syntax.h Tue Oct 6 19:27:01 1998 */
+/* From glibc's sysdeps/unix/sysv/linux/powerpc/sysdep.h */
+
+/* Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#define USE_PPC_PATCHES 1
+
+/* This seems to always be the case on PPC. */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+#define ASM_GLOBAL_DIRECTIVE .globl
+
+#ifdef __STDC__
+#define C_LABEL(name) C_SYMBOL_NAME(name)##:
+#else
+#define C_LABEL(name) C_SYMBOL_NAME(name)/**/:
+#endif
+
+#ifdef __STDC__
+#define L(body) .L##body
+#else
+#define L(body) .L/**/body
+#endif
+
+/* No profiling of gmp's assembly for now... */
+#define CALL_MCOUNT /* no profiling */
+
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#define EALIGN_W_0 /* No words to insert. */
+#define EALIGN_W_1 nop
+#define EALIGN_W_2 nop;nop
+#define EALIGN_W_3 nop;nop;nop
+#define EALIGN_W_4 EALIGN_W_3;nop
+#define EALIGN_W_5 EALIGN_W_4;nop
+#define EALIGN_W_6 EALIGN_W_5;nop
+#define EALIGN_W_7 EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+ past a 2^align boundary. */
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ C_LABEL(name)
+
+#undef END
+#define END(name) \
+ ASM_SIZE_DIRECTIVE(name)
+
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/Manifest b/grub-core/lib/libgcrypt/mpi/sparc32/Manifest
new file mode 100644
index 0000000..d279229
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32/Manifest
@@ -0,0 +1,24 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+udiv.S
+$names$ iQCVAwUAP+LmaDEAnp832S/7AQISHgP/Z5orU+CPKBeRFCogSQDm4p7J2VpDovU6mtfMTdjhqWuZG0U6y8WqH0aj3USfziOhtc8YjQHQ+97g3+EnIWZgLjKacWC6pScY/QbATEpF1D0Wrcea5rk3qR1t7isdBVVOrxedZ5vuj5Op2zx/0OlPI+wt6fTtW88BdG/a6w/ZU/8==Py6h
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/distfiles b/grub-core/lib/libgcrypt/mpi/sparc32/distfiles
new file mode 100644
index 0000000..a20f18e
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32/distfiles
@@ -0,0 +1,6 @@
+Manifest
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+udiv.S
+
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S
new file mode 100644
index 0000000..61a80ca
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S
@@ -0,0 +1,239 @@
+/* SPARC _add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr,
+ * mpi_ptr_t s1_ptr,
+ * mpi_ptr_t s2_ptr,
+ * mpi_size_t size)
+ */
+
+! INPUT PARAMETERS
+#define res_ptr %o0
+#define s1_ptr %o1
+#define s2_ptr %o2
+#define size %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n):
+ xor s2_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L1 ! branch if alignment differs
+ nop
+! ** V1a **
+L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
+ be L_v1 ! if no, branch
+ nop
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add size,-1,size
+ addcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+L_v1: addx %g0,%g0,%o4 ! save cy in register
+ cmp size,2 ! if size < 2 ...
+ bl Lend2 ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [s1_ptr+0],%g4
+ addcc size,-10,size
+ ld [s1_ptr+4],%g1
+ ldd [s2_ptr+0],%g2
+ blt Lfin1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop1: addxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+16],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+20],%g1
+ ldd [s2_ptr+16],%g2
+ std %o4,[res_ptr+8]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+24],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+28],%g1
+ ldd [s2_ptr+24],%g2
+ std %o4,[res_ptr+16]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+32],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+36],%g1
+ ldd [s2_ptr+32],%g2
+ std %o4,[res_ptr+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge Loop1
+ subcc %g0,%o4,%g0 ! restore cy
+
+Lfin1: addcc size,8-2,size
+ blt Lend1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1: addxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-2,size
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge Loope1
+ subcc %g0,%o4,%g0 ! restore cy
+Lend1: addxcc %g4,%g2,%o4
+ addxcc %g1,%g3,%o5
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc size,1,%g0
+ be Lret1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [s1_ptr+8],%g4
+ ld [s2_ptr+8],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[res_ptr+8]
+
+Lret1: retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+L1: xor s1_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L2
+ nop
+! ** V1b **
+ mov s2_ptr,%g1
+ mov s1_ptr,s2_ptr
+ b L0
+ mov %g1,s1_ptr
+
+! ** V2 **
+/* If we come here, the alignment of s1_ptr and res_ptr as well as the
+ alignment of s2_ptr and res_ptr differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of s1_ptr and s2_ptr are the same. */
+
+L2: cmp size,1
+ be Ljone
+ nop
+ andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
+ be L_v2 ! if no, branch
+ nop
+/* Add least significant limb separately to align s1_ptr and s2_ptr */
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add size,-1,size
+ addcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+
+L_v2: addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ blt Lfin2
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop2: ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ ldd [s1_ptr+8],%g2
+ ldd [s2_ptr+8],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+8]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+12]
+ ldd [s1_ptr+16],%g2
+ ldd [s2_ptr+16],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+16]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+20]
+ ldd [s1_ptr+24],%g2
+ ldd [s2_ptr+24],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+24]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+28]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge Loop2
+ subcc %g0,%o4,%g0 ! restore cy
+
+Lfin2: addcc size,8-2,size
+ blt Lend2
+ subcc %g0,%o4,%g0 ! restore cy
+Loope2: ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-2,size
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge Loope2
+ subcc %g0,%o4,%g0 ! restore cy
+Lend2: andcc size,1,%g0
+ be Lret2
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+Ljone: ld [s1_ptr],%g4
+ ld [s2_ptr],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+
+Lret2: retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S
new file mode 100644
index 0000000..3422ab0
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S
@@ -0,0 +1,97 @@
+/* sparc lshift
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+! INPUT PARAMETERS
+! res_ptr %o0
+! src_ptr %o1
+! size %o2
+! cnt %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift):
+ sll %o2,2,%g1
+ add %o1,%g1,%o1 ! make %o1 point at end of src
+ ld [%o1-4],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o0,%g1,%o0 ! make %o0 point at end of res
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ srl %g2,%o5,%g1 ! compute function result
+ be L0 ! if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+Loop0: ld [%o1-8],%g3
+ add %o0,-4,%o0
+ add %o1,-4,%o1
+ addcc %g4,-1,%g4
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne Loop0
+ st %o4,[%o0+0]
+
+L0: tst %o2
+ be Lend
+ nop
+
+Loop: ld [%o1-8],%g3
+ add %o0,-16,%o0
+ addcc %o2,-4,%o2
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+
+ ld [%o1-12],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+12]
+ srl %g2,%o5,%g1
+
+ ld [%o1-16],%g3
+ sll %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0+8]
+ srl %g3,%o5,%g1
+
+ ld [%o1-20],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+4]
+ srl %g2,%o5,%g1
+
+ add %o1,-16,%o1
+ or %g4,%g1,%g4
+ bne Loop
+ st %g4,[%o0+0]
+
+Lend: sll %g2,%o3,%g2
+ st %g2,[%o0-4]
+ retl
+ ld [%sp+80],%o0
+
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S
new file mode 100644
index 0000000..cd3db41
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S
@@ -0,0 +1,93 @@
+/* sparc rshift
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+! INPUT PARAMETERS
+! res_ptr %o0
+! src_ptr %o1
+! size %o2
+! cnt %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift):
+ ld [%o1],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ sll %g2,%o5,%g1 ! compute function result
+ be L0 ! if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+Loop0: ld [%o1+4],%g3
+ add %o0,4,%o0
+ add %o1,4,%o1
+ addcc %g4,-1,%g4
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne Loop0
+ st %o4,[%o0-4]
+
+L0: tst %o2
+ be Lend
+ nop
+
+Loop: ld [%o1+4],%g3
+ add %o0,16,%o0
+ addcc %o2,-4,%o2
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+
+ ld [%o1+8],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-16]
+ sll %g2,%o5,%g1
+
+ ld [%o1+12],%g3
+ srl %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0-12]
+ sll %g3,%o5,%g1
+
+ ld [%o1+16],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-8]
+ sll %g2,%o5,%g1
+
+ add %o1,16,%o1
+ or %g4,%g1,%g4
+ bne Loop
+ st %g4,[%o0-4]
+
+Lend: srl %g2,%o3,%g2
+ st %g2,[%o0-0]
+ retl
+ ld [%sp+80],%o0
+
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S b/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S
new file mode 100644
index 0000000..006b5c1
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S
@@ -0,0 +1,195 @@
+/* SPARC v7 __udiv_qrnnd division support, used from longlong.h.
+ * This is for v7 CPUs without a floating-point unit.
+ *
+ * Copyright (C) 1993, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+! INPUT PARAMETERS
+! rem_ptr o0
+! n1 o1
+! n0 o2
+! d o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+ tst %o3
+ bneg Largedivisor
+ mov 8,%g1
+
+ b Lp1
+ addxcc %o2,%o2,%o2
+
+Lplop: bcc Ln1
+ addxcc %o2,%o2,%o2
+Lp1: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln2
+ addxcc %o2,%o2,%o2
+Lp2: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln3
+ addxcc %o2,%o2,%o2
+Lp3: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln4
+ addxcc %o2,%o2,%o2
+Lp4: addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne Lplop
+ subcc %o1,%o3,%o4
+ bcc Ln5
+ addxcc %o2,%o2,%o2
+Lp5: st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Lnlop: bcc Lp1
+ addxcc %o2,%o2,%o2
+Ln1: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp2
+ addxcc %o2,%o2,%o2
+Ln2: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp3
+ addxcc %o2,%o2,%o2
+Ln3: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp4
+ addxcc %o2,%o2,%o2
+Ln4: addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne Lnlop
+ subcc %o4,%o3,%o1
+ bcc Lp5
+ addxcc %o2,%o2,%o2
+Ln5: st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Largedivisor:
+ and %o2,1,%o5 ! %o5 = n0 & 1
+
+ srl %o2,1,%o2
+ sll %o1,31,%g2
+ or %g2,%o2,%o2 ! %o2 = lo(n1n0 >> 1)
+ srl %o1,1,%o1 ! %o1 = hi(n1n0 >> 1)
+
+ and %o3,1,%g2
+ srl %o3,1,%g3 ! %g3 = floor(d / 2)
+ add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
+
+ b LLp1
+ addxcc %o2,%o2,%o2
+
+LLplop: bcc LLn1
+ addxcc %o2,%o2,%o2
+LLp1: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn2
+ addxcc %o2,%o2,%o2
+LLp2: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn3
+ addxcc %o2,%o2,%o2
+LLp3: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn4
+ addxcc %o2,%o2,%o2
+LLp4: addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne LLplop
+ subcc %o1,%g3,%o4
+ bcc LLn5
+ addxcc %o2,%o2,%o2
+LLp5: add %o1,%o1,%o1 ! << 1
+ tst %g2
+ bne Oddp
+ add %o5,%o1,%o1
+ st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+LLnlop: bcc LLp1
+ addxcc %o2,%o2,%o2
+LLn1: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp2
+ addxcc %o2,%o2,%o2
+LLn2: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp3
+ addxcc %o2,%o2,%o2
+LLn3: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp4
+ addxcc %o2,%o2,%o2
+LLn4: addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne LLnlop
+ subcc %o4,%g3,%o1
+ bcc LLp5
+ addxcc %o2,%o2,%o2
+LLn5: add %o4,%o4,%o4 ! << 1
+ tst %g2
+ bne Oddn
+ add %o5,%o4,%o4
+ st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Oddp: xnor %g0,%o2,%o2
+ ! q' in %o2. r' in %o1
+ addcc %o1,%o2,%o1
+ bcc LLp6
+ addx %o2,0,%o2
+ sub %o1,%o3,%o1
+LLp6: subcc %o1,%o3,%g0
+ bcs LLp7
+ subx %o2,-1,%o2
+ sub %o1,%o3,%o1
+LLp7: st %o1,[%o0]
+ retl
+ mov %o2,%o0
+
+Oddn: xnor %g0,%o2,%o2
+ ! q' in %o2. r' in %o4
+ addcc %o4,%o2,%o4
+ bcc LLn6
+ addx %o2,0,%o2
+ sub %o4,%o3,%o4
+LLn6: subcc %o4,%o3,%g0
+ bcs LLn7
+ subx %o2,-1,%o2
+ sub %o4,%o3,%o4
+LLn7: st %o4,[%o0]
+ retl
+ mov %o2,%o0
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest b/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest
new file mode 100644
index 0000000..dc1ce6a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest
@@ -0,0 +1,23 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+$names$ iQCVAwUAP+LmbjEAnp832S/7AQKQ2gQAotpCpY9rOJUCdZHbDLXXB9i1UUMraRKbVWimtKq493Y2d2wcqXCK2WaGs1AePK3K6Qk6msxZ0PL5Ho7KgHMkzsZ+wG0EUziiuX0yZRTWNm0r3TYerP6SdWH5GOVdSXn7ckkppk2sVOokfQTy+Tmrnah3+dlYJoujan+fmXWN6Us==DolM
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles b/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles
new file mode 100644
index 0000000..6e9a530
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles
@@ -0,0 +1,5 @@
+Manifest
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S
new file mode 100644
index 0000000..03fcdda
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S
@@ -0,0 +1,109 @@
+/* SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and
+ * store the product in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 8
+ .global C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1):
+ sll %o2,4,%g1
+ and %g1,(4-1)<<4,%g1
+#if PIC
+ mov %o7,%g4 ! Save return address register
+ call 1f
+ add %o7,LL-1f,%g3
+1: mov %g4,%o7 ! Restore return address register
+#else
+ sethi %hi(LL),%g3
+ or %g3,%lo(LL),%g3
+#endif
+ jmp %g3+%g1
+ ld [%o1+0],%o4 ! 1
+LL:
+LL00: add %o0,-4,%o0
+ add %o1,-4,%o1
+ b Loop00 /* 4, 8, 12, ... */
+ orcc %g0,%g0,%g2
+LL01: b Loop01 /* 1, 5, 9, ... */
+ orcc %g0,%g0,%g2
+ nop
+ nop
+LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
+ add %o1,4,%o1
+ b Loop10
+ orcc %g0,%g0,%g2
+ nop
+LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
+ add %o1,-8,%o1
+ b Loop11
+ orcc %g0,%g0,%g2
+
+Loop: addcc %g3,%g2,%g3 ! 1
+ ld [%o1+4],%o4 ! 2
+ st %g3,[%o0+0] ! 1
+ rd %y,%g2 ! 1
+Loop00: umul %o4,%o3,%g3 ! 2
+ addxcc %g3,%g2,%g3 ! 2
+ ld [%o1+8],%o4 ! 3
+ st %g3,[%o0+4] ! 2
+ rd %y,%g2 ! 2
+Loop11: umul %o4,%o3,%g3 ! 3
+ addxcc %g3,%g2,%g3 ! 3
+ ld [%o1+12],%o4 ! 4
+ add %o1,16,%o1
+ st %g3,[%o0+8] ! 3
+ rd %y,%g2 ! 3
+Loop10: umul %o4,%o3,%g3 ! 4
+ addxcc %g3,%g2,%g3 ! 4
+ ld [%o1+0],%o4 ! 1
+ st %g3,[%o0+12] ! 4
+ add %o0,16,%o0
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+Loop01: addcc %o2,-4,%o2
+ bg Loop
+ umul %o4,%o3,%g3 ! 1
+
+ addcc %g3,%g2,%g3 ! 4
+ st %g3,[%o0+0] ! 4
+ rd %y,%g2 ! 4
+
+ retl
+ addx %g0,%g2,%o0
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S
new file mode 100644
index 0000000..6f5cc43
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S
@@ -0,0 +1,132 @@
+/* SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and
+ * add the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1):
+ orcc %g0,%g0,%g2
+ ld [%o1+0],%o4 ! 1
+
+ sll %o2,4,%g1
+ and %g1,(4-1)<<4,%g1
+#if PIC
+ mov %o7,%g4 ! Save return address register
+ call 1f
+ add %o7,LL-1f,%g3
+1: mov %g4,%o7 ! Restore return address register
+#else
+ sethi %hi(LL),%g3
+ or %g3,%lo(LL),%g3
+#endif
+ jmp %g3+%g1
+ nop
+LL:
+LL00: add %o0,-4,%o0
+ b Loop00 /* 4, 8, 12, ... */
+ add %o1,-4,%o1
+ nop
+LL01: b Loop01 /* 1, 5, 9, ... */
+ nop
+ nop
+ nop
+LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
+ b Loop10
+ add %o1,4,%o1
+ nop
+LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
+ b Loop11
+ add %o1,-8,%o1
+ nop
+
+1: addcc %g3,%g2,%g3 ! 1
+ ld [%o1+4],%o4 ! 2
+ rd %y,%g2 ! 1
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] ! 1
+Loop00: umul %o4,%o3,%g3 ! 2
+ ld [%o0+4],%g1 ! 2
+ addxcc %g3,%g2,%g3 ! 2
+ ld [%o1+8],%o4 ! 3
+ rd %y,%g2 ! 2
+ addx %g0,%g2,%g2
+ nop
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+4] ! 2
+Loop11: umul %o4,%o3,%g3 ! 3
+ addxcc %g3,%g2,%g3 ! 3
+ ld [%o1+12],%o4 ! 4
+ rd %y,%g2 ! 3
+ add %o1,16,%o1
+ addx %g0,%g2,%g2
+ ld [%o0+8],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+8] ! 3
+Loop10: umul %o4,%o3,%g3 ! 4
+ addxcc %g3,%g2,%g3 ! 4
+ ld [%o1+0],%o4 ! 1
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+ ld [%o0+12],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+12] ! 4
+ add %o0,16,%o0
+ addx %g0,%g2,%g2
+Loop01: addcc %o2,-4,%o2
+ bg 1b
+ umul %o4,%o3,%g3 ! 1
+
+ addcc %g3,%g2,%g3 ! 4
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] ! 4
+ addx %g0,%g2,%o0
+
+ retl
+ nop
+
+
+! umul, ld, addxcc, rd, st
+
+! umul, ld, addxcc, rd, ld, addcc, st, addx
+
diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S
new file mode 100644
index 0000000..93bb194
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S
@@ -0,0 +1,67 @@
+/* SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1):
+ sub %g0,%o2,%o2 ! negate ...
+ sll %o2,2,%o2 ! ... and scale size
+ sub %o1,%o2,%o1 ! o1 is offset s1_ptr
+ sub %o0,%o2,%g1 ! g1 is offset res_ptr
+
+ mov 0,%o0 ! clear cy_limb
+
+Loop: ld [%o1+%o2],%o4
+ ld [%g1+%o2],%g2
+ umul %o4,%o3,%o5
+ rd %y,%g3
+ addcc %o5,%o0,%o5
+ addx %g3,0,%o0
+ subcc %g2,%o5,%g2
+ addx %o0,0,%o0
+ st %g2,[%g1+%o2]
+
+ addcc %o2,4,%o2
+ bne Loop
+ nop
+
+ retl
+ nop
+
+
diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/Manifest b/grub-core/lib/libgcrypt/mpi/supersparc/Manifest
new file mode 100644
index 0000000..869b97b
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/supersparc/Manifest
@@ -0,0 +1,21 @@
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+udiv.S
+$names$ iQCVAwUAP+LmdjEAnp832S/7AQIrUgQA3YmurZhK7r20DqRvg0gwNe9jMDcFfUY4ZPhW5HkGzMbmrxXtj5Dx50RIPteum72bXE+IhcngljQb/cskiN5Hi9oc2a2CPhyTqVFEeGyF+kJ170GI1pVfFOfzbVG0F4nEwm5lGHgv/nvFsvrjmmAXVW1v/yk5N35wbiLviOFrLOQ==byFc
diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/distfiles b/grub-core/lib/libgcrypt/mpi/supersparc/distfiles
new file mode 100644
index 0000000..ef7c0a5
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/supersparc/distfiles
@@ -0,0 +1,3 @@
+Manifest
+udiv.S
+
diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S b/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S
new file mode 100644
index 0000000..79e506a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S
@@ -0,0 +1,118 @@
+/* SuperSPARC __udiv_qrnnd division support, used from longlong.h.
+ * This is for SuperSPARC only, to compensate for its
+ * semi-functional udiv instruction.
+ *
+ * Copyright (C) 1993, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! rem_ptr i0
+! n1 i1
+! n0 i2
+! d i3
+
+#include "sysdep.h"
+#undef ret /* Kludge for glibc */
+
+ .text
+ .align 8
+LC0: .double 0r4294967296
+LC1: .double 0r2147483648
+
+ .align 4
+ .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+ !#PROLOGUE# 0
+ save %sp,-104,%sp
+ !#PROLOGUE# 1
+ st %i1,[%fp-8]
+ ld [%fp-8],%f10
+ sethi %hi(LC0),%o7
+ fitod %f10,%f4
+ ldd [%o7+%lo(LC0)],%f8
+ cmp %i1,0
+ bge L248
+ mov %i0,%i5
+ faddd %f4,%f8,%f4
+L248:
+ st %i2,[%fp-8]
+ ld [%fp-8],%f10
+ fmuld %f4,%f8,%f6
+ cmp %i2,0
+ bge L249
+ fitod %f10,%f2
+ faddd %f2,%f8,%f2
+L249:
+ st %i3,[%fp-8]
+ faddd %f6,%f2,%f2
+ ld [%fp-8],%f10
+ cmp %i3,0
+ bge L250
+ fitod %f10,%f4
+ faddd %f4,%f8,%f4
+L250:
+ fdivd %f2,%f4,%f2
+ sethi %hi(LC1),%o7
+ ldd [%o7+%lo(LC1)],%f4
+ fcmped %f2,%f4
+ nop
+ fbge,a L251
+ fsubd %f2,%f4,%f2
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ b L252
+ ld [%fp-8],%i4
+L251:
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ ld [%fp-8],%i4
+ sethi %hi(-2147483648),%g2
+ xor %i4,%g2,%i4
+L252:
+ umul %i3,%i4,%g3
+ rd %y,%i0
+ subcc %i2,%g3,%o7
+ subxcc %i1,%i0,%g0
+ be L253
+ cmp %o7,%i3
+
+ add %i4,-1,%i0
+ add %o7,%i3,%o7
+ st %o7,[%i5]
+ ret
+ restore
+L253:
+ blu L246
+ mov %i4,%i0
+ add %i4,1,%i0
+ sub %o7,%i3,%o7
+L246:
+ st %o7,[%i5]
+ ret
+ restore
+
diff --git a/grub-core/lib/libgcrypt/src/ChangeLog-2011 b/grub-core/lib/libgcrypt/src/ChangeLog-2011
new file mode 100644
index 0000000..3571fb1
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/ChangeLog-2011
@@ -0,0 +1,2398 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-09-16 Werner Koch <wk@g10code.com>
+
+ Change ATH code and turn the thread initialization callbacks in
+ the API into dummy functions.
+
+ * global.c (global_init): Call _gcry_pimegen_init.
+
+ * gcrypt.h.in (GCRY_THREAD_OPTI ON_VERSION): Bump to 1.
+ (GCRY_THREAD_OPTION_PTH_IMPL): Simplify.
+ (GCRY_THREAD_OPTION_PTHREAD_IMPL): Simplify.
+
+ * ath.c (ath_read, ath_write): Remove. They are only used in the
+ optional random-daemon.
+ (ath_select, ath_waitpid, ath_accept, ath_connect, ath_sendmsg)
+ (ath_recvmsg): Remove. They are not used.
+ * ath.h: Remove prototypes and corresponding structure fields.
+
+2011-03-11 Werner Koch <wk@g10code.com>
+
+ * ath.c (mutex_init): Rename second arg to FORCE and invert
+ logic. Change all callers.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (enum gcry_thread_option): Remove deprecated enum.
+ (gcry_md_start_debug, gcry_md_stop_debug): Remove deprecated these
+ macros.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ Removal of the gcry_ac and the module register interfaces.
+
+ * Makefile.am (include_HEADERS): Remove gcrypt-module.h.
+ (libgcrypt_la_SOURCES): Add gcrypt-module.h which is now internal
+ header.
+ * gcrypt-module.h (gcry_md_register, gcry_md_unregister): Remove.
+ (gcry_pk_register, gcry_pk_unregister): Remove.
+ (gcry_cipher_register, gcry_cipher_unregister): Remove.
+ * visibility.h: Include gcrypt-module.h.
+ * gcrypt.h.in: Do not include gcrypt-module.h.
+ * gcrypt.h.in: Remove all gcry_ac symbols.
+ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+ * visibility.h: Remove all gcry_ac symbols.
+ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+ (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
+ (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
+ * visibility.c: Remove all gcry_ac wrappers.
+ (gcry_pk_list, gcry_cipher_list, gcry_md_list): Remove.
+ (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
+ (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
+ * libgcrypt.vers: Remove all gcry_ac symbols.
+ (GCRYPT_1.2): Rename to GCRYPT_1.6.
+ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+ * libgcrypt.def: Remove all gcry_ac symbols.
+ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+ * global.c (global_init): Remove comment code with a call to
+ _gcry_ac_init.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (main): Fix endless loop when using pipe input and
+ option --binary.
+
+2011-06-10 Werner Koch <wk@g10code.com>
+
+ * sexp.c (vsexp_sscan): Add new format specifiers 'M' and 'u'.
+
+2011-05-24 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h (pk_operation): New.
+ (pk_encoding_ctx): Add new fields: op, nbits, flags, verify_cmp,
+ and verify_arg.
+
+2011-05-19 Daiki Ueno <ueno@unixuser.org>
+
+ * Makefile.am (gcryptrnd_LDADD): Supply $(GPG_ERROR_LIBS) for
+ gpg_strerror.
+
+2011-05-18 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h: Remove PUBKEY_FLAG_UNPAD.
+
+2011-05-11 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h (PUBKEY_FLAG_UNPAD): New.
+ (enum pk_encoding): New.
+ (struct pk_encoding_ctx): New.
+
+2011-04-19 Werner Koch <wk@g10code.com>
+
+ * stdmem.c (_gcry_private_malloc_secure, _gcry_private_malloc):
+ Set ERRNO on failure.
+ * secmem.c (mb_get_new): Set ERRNO on failure.
+ (_gcry_secmem_malloc_internal): Ditto.
+
+2011-04-01 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_realloc): Divert to gcry_malloc or gcry_free.
+
+2011-03-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_kdf_algos): New.
+ (gcry_kdf_derive): New.
+ * visibility.c (gcry_kdf_derive): New.
+ * visibility.h, libgcrypt.vers, libgcrypt.def: Add gcry_kdf_derive.
+
+2011-02-23 Werner Koch <wk@g10code.com>
+
+ * libgcrypt-config.in: Add option --host.
+ * libgcrypt.m4: Use AC_PROG_TOOL to find the config script. Print
+ a warning is the config scripts does not match the configure host.
+
+2011-02-21 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_check_version): Do not take the patchlevel in
+ account; it is not well defined.
+
+2011-02-17 Werner Koch <wk@g10code.com>
+
+ * gcrypt-module.h (gcry_cipher_register, gcry_cipher_unregister)
+ (gcry_pk_register, gcry_pk_unregister, gcry_md_register)
+ (gcry_md_unregister): Mark as deprecated by the API; in a future
+ version the module register feature will be removed.
+
+ * gcrypt.h.in: Attribute all _ac_ functions and types as
+ deprecated by the API.
+
+ * hwfeatures.c (detect_ia32_gnuc): Fix AES-NI detection. Use AND
+ instead of SUB for bit testing.
+
+2011-02-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRYCTL_DISABLE_HWF): New.
+ * global.c (_gcry_vcontrol): Support new control code.
+ (print_config): Factor list of hwfeatures out to ...
+ (hwflist): new.
+ (disabled_hw_features): New.
+ (global_init): Pass new variable to _gcry_detect_hw_features.
+ * hwfeatures.c (_gcry_detect_hw_features): Add arg
+ DISABLED_FEATURES and disable detected features.
+
+2011-02-11 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (HWF_INTEL_AES): Rename to HWF_INTEL_AESNI.
+ * hwfeatures.c (detect_ia32_gnuc): Fix setting of this flag.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_pk_get_curve, gcry_pk_get_param): New.
+ * libgcrypt.vers (gcry_pk_get_curve, gcry_pk_get_param): Add.
+ * libgcrypt.def (gcry_pk_get_curve, gcry_pk_get_param): Add.
+ * visibility.c (gcry_pk_get_curve, gcry_pk_get_param): New.
+ * cipher-proto.h (pk_extra_spec): Add fields GET_CURVE and
+ GET_CURVE_PARM.
+
+2011-01-31 Werner Koch <wk@g10code.com>
+
+ * sexp.c (vsexp_sscan): Allow opaque MPIs in "%m".
+
+2010-08-27 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (HWF_INTEL_AES): New.
+ * global.c (print_config): Print new flag.
+ * hwfeatures.c (detect_ia32_gnuc): Detect this flag.
+
+2010-08-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [!WIN32]: Add INSERT_SYS_SELECT_H autoconf substitute.
+
+2010-07-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [!__GNUC__ && W32]: Typedef ssize_t and pid_t to
+ help building with MSVC.
+
+2010-06-24 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [W32]: Include time.h and not sys/time.h.
+
+2010-04-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * misc.c (write2stderr): Dummy variable to silence gcc warning.
+
+2010-04-16 Marcus Brinkmann <marcus@g10code.de>
+
+ * sexp.c: (sexp_sscan): Make it variable length, and rename the
+ old version to ...
+ (vsexp_sscan): ... this new function. Also swap last two arguments.
+ (gcry_sexp_create): Remove dummy va_list.
+ (gcry_sexp_build): Use vsexp_sscan instead of sexp_sscan.
+ (_gcry_sexp_vbuild): Likewise.
+ (gcry_sexp_build_array): Remove dummy va_list.
+ (gcry_sexp_sscan): Likewise.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in: Add autoconf template to set generated file to
+ read-only in an Emacs buffer.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (arch_gpg_error_cflags, arch_gpg_error_libs): New.
+ (dumpsexp_CFLAGS): New.
+ (dumpsexp_LDADD): Add arch_gpg_error_libs.
+ (hmac256_CFLAGS, hmac256_LDADD): Add the arch variables.
+ (libgcrypt_la_DEPENDENCIES): Add libcompat.
+ * secmem.c (lock_pool): Mark unused args.
+ * global.c (do_malloc, gcry_realloc, gcry_free, gcry_calloc)
+ (gcry_calloc_secure, gcry_xcalloc, gcry_xcalloc_secure): Use
+ gpg_err_set_errno.
+ (_gcry_vcontrol): Call _gcry_compat_identification.
+ * hmac256.c [__MINGW32CE__]: Include gpg-error.h.
+ (_gcry_hmac256_file): Use gpg_err_set_errno.
+ (gpg_err_set_errno) [!GPG_ERR_INLINE]: Add macro.
+ * g10lib.h: Include libcompat.h.
+
+2010-01-05 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_PK_ECDH): New.
+
+2009-12-08 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_CIPHER_MODE_AESWRAP): New.
+
+2009-12-08 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (LTRCCOMPILE): Refactor with ...
+ (RCCOMPILE): ... this new macro. Add $(libgcrypt_la_CPPFLAGS).
+ (SUFFIXES): Add .lo.
+ (.rc.o): Change to ...
+ (.rc.lo): ... this implicit rule.
+ (gcrypt_res_ldflag): Removed.
+ (gcrypt_res): Use libtool object file name here.
+ (libgcrypt_la_LDFLAGS): Remove gcrypt_res_ldflag usage.
+ (libgcrypt_la_LIBADD): Add gcrypt_res.
+
+2009-11-29 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Repalce "=r" by "+r" so that
+ HAS-CPUDID is always initialized. Thanks to Ben Hutchings for
+ pointing out this problem.
+
+2009-08-05 Werner Koch <wk@g10code.com>
+
+ * ath.h: Include sys/msg.h.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Do not use FIPS mode if
+ /proc/.../fips_enabled has insufficient permissions.
+
+ * dumpsexp.c (main): Fix handling multiple files.
+ (parse_and_print): Implement hex and octal escaping.
+
+ * sexp.c (unquote_string): Remove superfluous clearing of ESC.
+ * dumpsexp.c (parse_and_print): Add missing break.
+ (main): Fix return value.
+ Reported by Fabian Keil.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * ath.h [HAVE_SYS_SELECT_H]: Include <sys/select.h> for fd_set.
+ [!HAVE_SYS_SELECT_H]: Include <sys/time.h>. Move inclusion of
+ config.h to the top. The actual configure check was already
+ there.
+
+ * sexp.c: Remove memory.h.
+ * mpi.h: Remove memory.h. Add string.h.
+
+2009-02-02 Werner Koch <wk@g10code.com>
+
+ * ath.h: Include sys/time.h. Fixes bug#993.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Remove superfluous const
+ from static string. Reported by Albert Chin.
+ * hmac256.c (selftest): Ditto and change to unsigned char.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (finalize): Fix for big endian hosts.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_free): Save and restore ERRNO if set.
+
+2008-11-24 Werner Koch <wk@g10code.com>
+
+ * sexp.c (get_internal_buffer): New.
+ (sexp_sscan): Add format character S.
+ * cipher-proto.h (pk_ext_generate_t): Add field EXTRAINFO changed
+ all implementors.
+
+ * cipher-proto.h (pk_ext_generate_t): Simplify.
+ (pk_get_param): New.
+ (pk_extra_spec_t): Add field GET_PARAM.
+ * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): Remove.
+ (_gcry_pubkey_extraspec_elg): New.
+
+2008-11-05 Werner Koch <wk@g10code.com>
+
+ * cipher.h (CIPHER_INFO_NO_WEAK_KEY): New.
+
+ * cipher-proto.h (cipher_set_extra_info_t): New.
+ (cipher_extra_spec): Add field SET_EXTRA_INFO.
+
+2008-10-30 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (GCC_ATTR_FORMAT_ARG): New.
+ (_gcry_gettext): Use it.
+
+2008-10-24 Werner Koch <wk@g10code.com>
+
+ * global.c (inactive_fips_mode): Move to fips.c.
+ (gcry_set_allocation_handler): Factor code out to ...
+ * fips.c (_gcry_inactivate_fips_mode): New.
+ (_gcry_is_fips_mode_inactive): New.
+
+2008-09-29 Werner Koch <wk@g10code.com>
+
+ * gcrypt-module.h (GCRY_MODULE_ID_USER, GCRY_MODULE_ID_USER_LAST):
+ New.
+ * module.c (MODULE_ID_USER, MODULE_ID_USER_LAST): Define using new
+ macros.
+
+2008-09-20 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (finalize) [WORDS_BIGENDIAN]: Fix sigbus problem.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * cipher-proto.h (pk_ext_generate_t): Add args QBITS, NAME, DOMAIN.
+
+ * fips.c (fips_new_state): Allow Error => Error transition.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_fips_mode_active): New.
+
+ * secmem.c (_gcry_secmem_init): Factor most code out to ..
+ (secmem_init): .. new.
+ (DEFAULT_POOL_SIZE): Rename to MINIMUM_POOL_SIZE.
+ (STANDARD_POOL_SIZE): New.
+ (_gcry_secmem_malloc_internal): Don't abort if the pool is not
+ initialized but try to out intialize it first and only then print
+ an error message and return NULL. If the pool is not locked while
+ in FIPS mode, return NULL.
+
+ * fips.c (FIPS_FORCE_FILE): New constant. Change the file name to
+ "/etc/gcrypt/fips_enabled".
+ (enforced_fips_mode): New.
+ (_gcry_initialize_fips_mode): Set that flag.
+ (_gcry_enforced_fips_mode): New.
+ * global.c (inactive_fips_mode): New.
+ (_gcry_vcontrol): Take that flag in account for GCRYCTL_FIPS_MODE_P.
+ (gcry_set_allocation_handler): Take care of the enforced fips mdoe
+ flag.
+ (get_no_secure_memory): New.
+ (do_malloc, gcry_is_secure): Use it.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * global.c (print_config): Use y/n for fips mode.
+
+ * fips.c (fips_new_state): Allow transition to Error and
+ Fatal-error from Init.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * fips.c [HAVE_SYSLOG]: Include syslog.h.
+ (_gcry_initialize_fips_mode, lock_fsm, unlock_fsm)
+ (_gcry_fips_signal_error, fips_new_state)
+ (_gcry_fips_noreturn) [HAVE_SYSLOG]: Also log via syslog.
+ (check_binary_integrity) [HAVE_SYSLOG]: Log failure.
+ * global.h [HAVE_SYSLOG]: Include syslog.h.
+ (_gcry_global_is_operational) [HAVE_SYSLOG]: Print warning.
+
+ * global.c (_gcry_vcontrol): Use GCRYCTL_INITIALIZATION_FINISHED
+ to run power-up tests. Add unpublished control commands 58-60.
+
+ * global.c (_gcry_global_is_operational): New.
+ * g10lib.h (fips_is_operational): Change to call this function.
+
+2008-09-12 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_fips_run_selftests): Add arg EXTENDED.
+ (run_cipher_selftests, run_digest_selftests, run_hmac_selftests)
+ (run_pubkey_selftests): Ditto.
+ * cipher-proto.h (selftest_func_t): Add arg EXTENDED
+
+2008-09-11 Werner Koch <wk@g10code.com>
+
+ * fips.c: Include string.h.
+ (loxtoi_1, loxtoi_2, loxdigit_p): New.
+ (check_binary_integrity): Change the format of the expected file.
+
+ * fips.c (_gcry_fips_run_selftests): Run random tests before the
+ pubkey tests.
+
+2008-09-05 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCYRCTL_SELFTEST): New.
+ * global.c (_gcry_vcontrol): Implement.
+ * fips.c (_gcry_fips_run_selftests): Do state transitions only if
+ in fips mode. Return an error code.
+
+2008-09-01 Werner Koch <wk@g10code.com>
+
+ * stdmem.c: Re-indented.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Changed /proc file to test
+ for FIPS mode.
+
+ * cipher-proto.h (pk_compute_keygrip_t): New.
+ (pk_extra_spec): Add field comp_keygrip.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (_gcry_detect_hw_features): Disable hardware
+ detection in FIPS mode.
+
+2008-08-27 Werner Koch <wk@g10code.com>
+
+ * global.c (_gcry_vcontrol): Allow running selftests from error
+ state.
+ (gcry_set_outofcore_handler): Only print a warning if used in FIPS
+ mode.
+ (gcry_xmalloc, gcry_xrealloc, gcry_xmalloc_secure, gcry_xstrdup):
+ Ignore an outofcore handler in FIPS mode.
+
+ * fips.c (_gcry_fips_test_error_or_operational): New.
+ (fips_new_state): Allow transition from error into selftest.
+ Disallow error to init.
+
+2008-08-26 Werner Koch <wk@g10code.com>
+
+ * fips.c (fips_new_state): Print state transitions only at
+ verbosity level of 2.
+ (reporter): Likewise.
+
+ * cipher-proto.h (pk_ext_generate_t): New.
+ (pk_extra_spec): Add member ext_generate.
+ * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): New.
+
+2008-08-22 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (_gcry_hmac256_file): New.
+ (main): New option --binary.
+ * fips.c (check_binary_integrity): New.
+ (_gcry_fips_run_selftests): Run it.
+
+ * global.c (_gcry_vcontrol) <GCRYCTL_UPDATE_RANDOM_SEED_FILE>:
+ Check for fips operational state.
+ (_gcry_vcontrol) <GCRYCTL_FAST_POLL>: Ditt.
+
+2008-08-21 Werner Koch <wk@g10code.com>
+
+ * misc.c (_gcry_log_printhex): New.
+
+2008-08-20 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (gcry_assert): New. use this at almost all places
+ where we used a plain assert.
+ * misc.c (_gcry_assert_failed): New.
+ (_gcry_bug): Also use func variant for ISO-C99.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * visibility.c, visibility.h (gcry_mpi_lshift): New.
+ * libgcrypt.vers, libgcrypt.def, gcrypt.h.in: Ditto.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_cipher_setkey): Replace macro by function.
+ (gcry_cipher_setiv): Ditto.
+ (gcry_cipher_setctr): Ditto.
+ * visibility.c (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * visibility.h (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * libgcrypt.vers (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * libgcrypt.def (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+
+ * hmac256.h, hmac256.c: New.
+ * Makefile.am (hmac256_SOURCES): New.
+ * Makefile.am (bin_PROGRAMS): Add hmac256.
+
+ * gcrypt.h.in (struct gcry_thread_cbs): Change type of OPTION to
+ unsigned int. Although this is a type change it does not make a
+ difference.
+ * ath.c (ath_install): Take the version of the option field in
+ account.
+
+ * visibility.c (gcry_pk_encrypt, gcry_pk_decrypt, gcry_pk_sign)
+ (gcry_pk_verify, gcry_pk_testkey, gcry_pk_genkey)
+ (gcry_pk_get_nbits, gcry_pk_get_keygrip)
+ (gcry_md_open, gcry_md_copy, gcry_md_enable)
+ (gcry_md_write, md_final, gcry_md_ctl, gcry_md_setkey)
+ (gcry_md_hash_buffer, gcry_md_get_algo, gcry_md_info)
+ (gcry_md_is_enabled)
+ (gcry_cipher_open, gcry_cipher_encrypt)
+ (gcry_cipher_decrypt, gcry_cipher_ctl)
+ (gcry_cipher_algo_info): Check whether the library is operational.
+
+ * cipher-proto.h: New.
+ * cipher.h: Include cipher-proto.h.
+ * visibility.h: Remove duplicate macro definitions. Remove
+ gcry_cipher_register, gcry_md_register, gcry_pk_register macros.
+ * visibility.c: Include cipher-proto.h.
+ (gcry_cipher_register): Pass dummy extra args to the internal
+ register function.
+ (gcry_md_register, gcry_pk_register): Ditto.
+ * g10lib.h (struct gcry_module): Add field EXTRASPEC.
+ * module.c (_gcry_module_add): Add arg EXTRASPEC. Changed all
+ callers to pass NULL.
+
+ * fips.c: New.
+ * gcrypt.h.in (GCRYCTL_FIPS_MODE_P): New.
+ * global.c (global_init): Call fips initialization.
+ (_gcry_vcontrol): Add GCRYCTL_FIPS_MODE_P code.
+ (print_config): Add config item fips-mode.
+ (gcry_set_allocation_handler): Do not allow the use of custom
+ allocation handlers.
+ (gcry_set_outofcore_handler): Ditto.
+ (_gcry_get_debug_flag): Do not return any debug flags in fips mode.
+ * misc.c (_gcry_logv): Signal fips error on BUG or FATAL.
+ (_gcry_fatal_error): Ditto.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Include librandom.la.
+
+2008-04-18 Werner Koch <wk@g10code.com>
+
+ * missing-string.c (vasprintf): Remove. It is not used. Reported
+ by Simon Josefsson.
+
+2008-03-11 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_ac_em_t, gcry_ac_scheme_t): Remove trailing
+ comma for full C-89 compatibility.
+
+2008-01-21 Marcus Brinkmann <marcus@g10code.de>
+
+ * hwfeatures.c (detect_ia32_gnuc): Fix inline asm.
+
+2007-12-11 Werner Koch <wk@g10code.com>
+
+ * visibility.c (gcry_md_hash_buffer): Don't use return vor a void
+ function. Hey, why does gcc not complain about this?
+ (gcry_ac_io_init_va): Ditto.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Depend on ENABLE_PADLOCK_SUPPORT.
+
+2007-12-03 Werner Koch <wk@g10code.com>
+
+ * misc.c (_gcry_logv): Use abort for error levels fatal and bug as
+ this is more approriate for a library. Terminate the secmem
+ before doing so.
+ (_gcry_fatal_error): Terminate secmem before abort.
+ * secmem.c (_gcry_secmem_malloc_internal): Use log_bug instead of
+ exit.
+
+2007-11-29 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Detect Padlock engine.
+
+2007-11-13 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (_GCRY_GCC_ATTR_MALLOC): Fixed gcc version check.
+ Reported by Gabriele Monti.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_control): Factor most code out to ..
+ (_gcry_vcontrol): .. new.
+ * sexp.c (_gcry_sexp_vbuild): New.
+ * mpi.h (_gcry_mpi_set, _gcry_mpi_set_ui, _gcry_mpi_invm): Remove
+ prototypes as they are already in gcrypt.h.
+
+2007-10-30 Werner Koch <wk@g10code.com>
+
+ * sexp.c (gcry_sexp_nth_string): Replace by _gcry_sexp_nth_string.
+
+ * visibility.h, visibility.c: New.
+ * g10lib.h: Include visibility.h instead of gcrypt.h.
+ * globals.c (_gcry_malloc): Rename to ..
+ (do_malloc): .. this.
+
+ * hwfeatures.c: New.
+ * global.c (global_init): Detect features.
+ (print_config): Print them.
+
+2007-08-22 Werner Koch <wk@g10code.com>
+
+ * dumpsexp.c: New.
+ * Makefile.am (bin_PROGRAMS): Install it.
+
+ * getrandom.c (print_version): Use new standard license line.
+ * gcryptrnd.c (print_version): Ditto.
+
+2007-06-06 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTH_IMPL): Factror network
+ related code out so that the prototypes can be adjusted for W32.
+ (_GCRY_THREAD_OPTION_PTH_IMPL_NET): New.
+
+2007-05-09 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.m4: Print found version on success.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in (gcry_ac_io_t): Add name for anonymous union, and mark
+ all members as internal (actually: deprecated).
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (.rc.lo): New to replace gmake specific suffix rule.
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.def (gcry_sexp_nth_string): New.
+ * Makefile.am (EXTRA_DIST): Add libgcrypt.def.
+
+2007-05-02 Werner Koch <wk@g10code.com>
+
+ * global.c (print_config): Print ciphers, digests and pubkeys.
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * cipher.h, gcrypt.h.in: Add Camellia.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRYCTL_PRINT_CONFIG): New.
+ (GCRYCTL_SET_RNDEGD_SOCKET): New.
+ * global.c (gcry_control): Add GCRYCTL_PRINT_CONFIG and
+ GCRYCTL_SET_RNDEGD_SOCKET.
+ (print_config): New.
+ * misc.c (_gcry_log_info_with_dummy_fp): New.
+
+2007-04-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_sexp_nth_string): New.
+
+ * sexp.c (gcry_sexp_nth_data): Factored code out to ...
+ (sexp_nth_data): ... new.
+ (gcry_sexp_nth_string): New.
+ (gcry_sexp_nth_mpi): Reimplemented in terms of sexp_ntd_data.
+
+2007-04-16 Werner Koch <wk@g10code.com>
+
+ * secmem.c (init_pool): Use sysconf() if available to determine
+ page size.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * mpi.h (mpi_mod): New.
+ (mpi_new, mpi_snew): New.
+
+ * gcrypt.h.in: Add GCRY_PK_ECDSA.
+
+2007-03-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Fixed typo
+ introduced by me on 2006-10-23.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_ac_id_to_name, gcry_ac_name_to_id): Mark as
+ deprecated.
+
+ * libgcrypt.def (gcry_fast_random_poll): Removed - it is a macro.
+ (gcry_cipher_register, gcry_cipher_unregister): New.
+ (gcry_md_register, gcry_md_unregister): New.
+ (gcry_pk_register, gcry_pk_unregister): New.
+ (gcry_ac_data_from_sexp, gcry_ac_data_to_sexp): New.
+ (gcry_ac_io_init, gcry_ac_io_init_va): New.
+ (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme): New.
+ (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): New.
+
+ * missing-string.c: Include stdio.h for the vsprintf prototype.
+
+ * ath.h (struct ath_ops) [_WIN32]: Use int instead of socklen_t.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.def (gcry_create_nonce, gcry_fast_random_poll)
+ (gcry_md_debug): New.
+
+ * libgcrypt-config.in: Remove duplicates from --cflags and --libs.
+ Print a error for option --thread.
+
+ * gcrypt.h.in (gcry_sexp_sprint): Change BUFFER from char* to void*.
+ (gcry_md_ctl): Change BUFFER from unsigned char* to void*.
+ (gcry_md_debug): New.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Change buffer args to
+ void*.
+ (gcry_randomize): Change BUFFER to void.
+ (gcry_create_nonce): Ditto.
+
+ * libgcrypt.vers (gcry_md_debug): New.
+
+ * sexp.c (gcry_sexp_sprint): Ditto.
+ (normalize): Make P unsigned.
+ (gcry_sexp_nth_data): Cast return value to char*.
+ (sexp_sscan): Fix sign/unsigned conflicts.
+ (whitespacep): Change P to char*.
+ (unquote_string): Change STRING to char*.
+ (convert_to_hex): Change DEST to char*.
+ (convert_to_string): Change DEST and P to char*.
+ (convert_to_token): Chnage DEST to char*.
+ (gcry_sexp_canon_len): Change DISPHINT to unsigned char*.
+
+ * gcrypt-module.h (gcry_pk_spec): Made ALIASES a const.
+ (gcry_md_write_t): Changed BUF to a const void*.
+
+2007-02-12 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in: Include stdlib.h for the sake fo the trheading
+ macros. Suggested by Andreas Metzler.
+
+ * secmem.c (ptr_into_pool_p): New.
+ (_gcry_private_is_secure): Implement in terms of new function.
+ (BLOCK_VALID): Removed. Replaced all users by new function.
+
+2007-01-31 Werner Koch <wk@g10code.com>
+
+ * secmem.c (_gcry_private_is_secure): Fixed severe implementation
+ flaw. Might be the reason for some of the more obscure bugs.
+ (MB_WIPE_OUT): Use wipememory2.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Add some cast for
+ use by C-doubleplus. In general I don't like this but due to
+ public demand I give up ;-)
+
+2006-10-19 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_control) <GCRYCTL_INIT_SECMEM>: Return an error
+ if the memory could not be locked.
+ * secmem.c (not_locked): New.
+ (_gcry_secmem_get_flags): Return that flag.
+ * secmem.h (GCRY_SECMEM_FLAG_NOT_LOCKED): New.
+
+2006-10-05 Werner Koch <wk@g10code.com>
+
+ * module.c (_gcry_module_id_new): Don't assign modules in the range
+ the range of 1024..4096.
+ * gcrypt.h (GCRY_MD_USER, GCRY_MD_USER_LAST): New
+ (GCRY_PK_USER, GCRY_PK_USER_LAST): New.
+ (GCRY_CIPHER_USER, GCRY_CIPHER_USER_LAST): New.
+
+2006-10-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in: Replace socklen_t with gcry_socklen_t.
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in: Replace version by @VERSION@.
+
+2006-10-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h: Add fallback type for socklen_t. Move to ...
+ * gcrypt.h.in: ... this file.
+ * Makefile.am (EXTRA_DIST): Add gcrypt.h.in.
+
+2006-09-04 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Removed some trailing comma in enums.
+
+2006-08-29 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_xrealloc): Pass secure flag to outofcore handler.
+
+ * gcrypt.h (GCRY_CIPHER_SEED): New.
+
+2006-08-21 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRYCTL_FAKED_RANDOM_P): New.
+
+2006-07-29 Marcus Brinkmann <marcus@g10code.de>
+
+ * secmem.c (init_pool): Close FD after establishing the mapping.
+
+2006-07-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * ath.c (ath_mutex_destroy): Microoptimize destruction of unused
+ statitically initialized mutexes. Suggested by Victor Stinner
+ <victor.stinner@inl.fr>.
+
+ * gcrypt.h (GCRY_THREAD_OPTION_PTHREAD_IMPL,
+ (GCRY_THREAD_OPTION_PTH_IMPL): Add missing initializers to
+ suppress gcc warning.
+ Submitted by Victor Stinner <victor.stinner@inl.fr>.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * ath.c: Avoid warning about double defined type byte and other
+ hacks to let it build for W32 (backported from LIBGCRYPT-1-2-BRANCH).
+ * ath.h, gcrypt.h, tests/benchmark.c, src/types.h: Likewise.
+
+ * gcrypt.h: Revert last change, and instead:
+ [_WIN32 || __WIN32__]: Do not include <sys/socket.h>, but
+ <winsock2.h> and <ws2tcpip.h>.
+ Suggested by Simon Josefsson <jas@extundo.com>.
+
+ * Makefile.am (install-data-local, uninstall-local, %.lo,
+ (install-def-file, uninstall-def-file): New targets.
+ (LTRCCOMPILE, gcrypt_res, gcrypt_res_ldflag, no_undefined,
+ (export_symbols, gcrypt_deps): New variables.
+ * versioninfo.rc.in: New file.
+ * libgcrypt.def: New file from ../w32-dll/libgcrypt.def.
+
+ * gcrypt.h [!HAVE_SYS_SOCKET_H]: Do not include sys/socket.h, but
+ the appropriate windows socket header.
+
+2006-06-21 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_xcalloc, gcry_xcalloc_secure): Made safe against
+ integer overflow.
+
+ * sexp.c (make_space): Return an error on out of core.
+ (sexp_sscan): Remove all xmalloc style calls and return proper
+ error codes on allocation failures.
+ (gcry_sexp_find_token): Ditto.
+ (gcry_sexp_nth):
+
+ * sexp.c (gcry_sexp_find_token): Re-indented and removed a cruft
+ "while(level);" which fortunately had no effect.
+
+2006-04-28 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRY_MD_SHA224): Change value from 306 to 11 to match
+ the use in OpenPGP. There has been no release yet, so we can
+ safely do it.
+
+2006-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_ctl_cmds): New commands:
+ GCRYCTL_SET_RANDOM_DAEMON_SOCKET, GCRYCTL_USE_RANDOM_DAEMON.
+ * global.c (gcry_control): Handle new commands, calling
+ _gcry_set_random_daemon_socket() and _gcry_use_random_daemon().
+
+2006-04-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRY_PK_USAGE_CERT, GCRY_PK_USAGE_AUTH)
+ (GCRY_PK_USAGE_UNKN): New.
+
+2006-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_ac_eme_pkcs_v1_5): Removed members: key, handle;
+ added member: key_size.
+
+ * secmem.c (MB_FLAG_ACTIVE): Write braces around MB_FLAG_ACTIVE
+ definition.
+
+2006-03-15 Werner Koch <wk@g10code.com>
+
+ * getrandom.c: New.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * gcryptrnd.c: New.
+
+2006-03-10 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Add GCRY_MD_SHA224.
+
+2005-11-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Update comments for functions: gcry_cipher_algo_name,
+ gcry_pk_algo_name.
+
+2005-10-31 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Added documentation.
+
+2005-10-16 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (global_init): Use gcry_error_t instead of
+ gcry_err_code_t; use goto instead of if constructs.
+
+ * stdmem.c: Inserted description of the layered memory management
+ in Libgcrypt.
+
+ * g10lib.h: Removed G10_I18N_H related check; it seems to be a
+ GnuPG relict (Libgcrypt does not define this symbol anywhere).
+ (FLAG_MODULE_DISABLED): Don't forget parantheses around shifted
+ value.
+
+ Removed GCC_ATTR_PURE macro definitions, since gcrypt.h does
+ already contain such a macro named _GCRY_GCC_ATTR_PURE, which we
+ can use here as well.
+
+ Likewise for GCC_ATTR_MALLOC and _GCRY_GCC_ATTR_MALLOC.
+
+ * stdmem.h: Use _GCRY_GCC_ATTR_MALLOC instead of GCC_ATTR_MALLOC.
+ * secmem.h: Likewise.
+
+2005-10-09 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_control): Call global_init() after passing thread
+ cbs to ath. global_init() MUST to be called AFTER passing the cbs
+ to ath and BEFORE calling library functions, which make use of
+ ath. This change combines cbs installing with ath initialization
+ and thus removes the need to call other library initialization
+ functions inbetween like e.g. gcry_check_version().
+
+2005-10-01 Moritz Schulte <moritz@g10code.com>
+
+ * ath.c: Assign copyright to FSF.
+ * ath.h: Likewise.
+
+2005-06-25 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (pkgconfigdir, pkgconfig_DATA): Removed variables.
+ * libgcrypt.pc.in: Removed file - we do not want to support a
+ second, foreign configuration system.
+
+2005-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_xstrdup): Removed superfluous strcpy call.
+
+2005-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (pkgconfigdir, pkgconfig_DATA): New; support for
+ pkgconfig provided by Albert Chin.
+ * libgcrypt.pc.in (Cflags): New file.
+
+2005-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h (_gcry_ac_init): Declare.
+ * global.c (global_init): Call _gcry_ac_init; don't forget to set
+ err.
+
+2005-04-14 Werner Koch <wk@g10code.com>
+
+ * sexp.c (whitespacep): New.
+ (sexp_sscan): Replaced isdigit and isspace by whitespacep and
+ digitp.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_md_algos): Added: GCRY_MD_WHIRLPOOL.
+ * cipher.h (_gcry_digest_spec_whirlpool): Declare.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * libgcrypt.vers: Added: gcry_ac_io_init, gry_ac_io_init_va.
+
+ * gcrypt.h (gcry_ac_data_read_cb_t, gcry_ac_data_write_cb_t,
+ gcry_ac_io_mode_t, gcry_ac_io_type_t, gcry_ac_io_t): New types.
+ (gcry_ac_io_init_va): Declare function.
+ (gcry_ac_data_encode, gcry_ac_data_decode,
+ gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme,
+ gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): Use
+ gcry_ac_io_type_t objects instead of memory strings directly.
+
+2005-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * libgcrypt.vers: Added: gcry_ac_data_to_sexp() and
+ gcry_ac_data_from_sexp().
+
+2005-02-22 Werner Koch <wk@g10code.com>
+
+ * global.c (_gcry_malloc): Make sure ERRNO is set if we return
+ NULL. Remove unneeded initialization of M to allow the compiler
+ to catch errors.
+ (gcry_realloc): Make sure ERRNO is set if we return NULL>
+
+2005-02-13 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declare new functions: gcry_ac_data_encrypt_scheme,
+ gcry_ac_data_decrypt_scheme, gcry_ac_data_sign_scheme,
+ gcry_ac_data_verify_scheme, gcry_ac_data_encode,
+ gcry_ac_data_decode, gcry_ac_data_to_sexp, gcry_ac_data_from_sexp.
+ New types: gcry_ac_emsa_pkcs_v1_5_t, gcry_ac_ssa_pkcs_v1_5_t,
+ gcry_md_algo_t.
+ New enumeration lists: gcry_ac_scheme_t, gcry_ac_em_t.
+ * libgcrypt.vers: Added new ac functions.
+ * g10lib.h: Declare function: _gcry_pk_get_elements.
+ * mpi.h (mpi_get_ui): New macro.
+ Declare function: _gcry_mpi_get_ui.
+
+2004-11-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Removed 3 trailing commas from enums. Noted by Heiko
+ Stamer.
+
+2004-09-21 Werner Koch <wk@g10code.de>
+
+ * sexp.c (sexp_sscan): Removed C++ style comments. Noted by Yoann
+ Vandoorselaere.
+
+2004-08-23 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Do not include <assert.h>.
+ * sexp.c: Likewise.
+ * module.c: Likewise.
+ * misc.c: Likewise.
+
+2004-08-18 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (_gcry_secmem_init): Try to lock pool into core not
+ only when running with root privileges.
+
+2004-08-16 Werner Koch <wk@g10code.de>
+
+ * secmem.h (_gcry_secmem_set_flags,_gcry_secmem_get_flags):
+ Removed __pure__.
+ (GCRY_SECMEM_FLAG_NO_WARNING): Put macro value into parens.
+
+ * secmem.c (_gcry_secmem_init): Defer printing of the warning.
+
+2004-08-10 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Include <sys/time.h>, thanks to Simon Josefsson.
+
+2004-05-07 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRYCTL_FAST_POLL.
+ (gcry_fast_random_poll): New.
+ * global.c (gcry_control) <INITIALIZATION_FINISHED>: Do only basic
+ random subsystem init.
+ (gcry_control) <FAST_POLL>: New.
+
+2004-04-22 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt.m4: Quote first argument to AC_DEFUN.
+
+2004-04-15 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_malloc_internal): Removed old extra info
+ error output.
+ (_gcry_secmem_term): Use wipememory2 here.
+
+ * misc.c (_gcry_burn_stack): Use wipememory to avoid optimizations.
+
+ * string.c: Removed. Was never used.
+ * global.c (gcry_strdup): Replaced by the version from string.c
+ (gcry_xstrdup): Rewritten.
+ * gcrypt.h: Removed duplicate prototype for gcry_strdup.
+
+2004-03-29 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_realloc): Fixed double unlock; bug
+ manifested itself due to the more rigorous checking in the changed
+ ath.h
+
+ * libgcrypt-config.in (Options): Ignore the obsolete --threads
+ option for now.
+
+2004-03-17 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt-config.in (includedir, libdir): Quote'em. Use
+ $gpg_error_cflags and $gpg_error_libs. Fix construction of
+ $includes.
+
+2004-03-14 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt-config.in (includedir, libdir): New variables. For
+ --cflags, don't test $cflags. Also check against /include for the
+ GNU/Hurd. Don't overwrite but extend $cflags_final. Likewise for
+ --libs.
+
+2004-03-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (ltlib_libgcrypt_pthread, ltlib_libgcrypt_pth): Removed.
+ (lib_LTLIBRARIES): Remove those variables from here.
+ (libgcrypt_pthread_la_SOURCES, libgcrypt_pthread_la_LDFLAGS,
+ (libgcrypt_pthread_la_DEPENDENCIES, libgcrypt_pthread_la_LIBADD,
+ (libgcrypt_pth_la_SOURCES, libgcrypt_pth_la_LDFLAGS,
+ (libgcrypt_pth_la_DEPENDENCIES, libgcrypt_pth_la_LIBADD,
+ (noinst_LTLIBRARIES): Removed.
+ (libgcrypt_real_la_SOURCES): Merge with ...
+ (libgcrypt_la_SOURCES): ... likewise.
+ (libgcrypt_real_la_DEPENDENCIES): Merge with ...
+ (libgcrypt_la_DEPENDENCIES): ... this.
+ (libgcrypt_real_la_LIBADD): Merge with ...
+ (libgcrypt_la_LIBADD): ... this.
+ * libgcrypt-config.in (libs_pthread, libs_pth, cflags_pth)
+ (cflags_pthread, thread_module, thread_modules): Removed.
+ (Options): Remove --thread option from help output. If the option
+ is specified, output an error and exit.
+ For --cflags and --libs option, remove pth and pthread from output.
+ * gcrypt.h: Include <sys/types.h> and <sys/socket.h>.
+ (enum gcry_ctl_cmds): Add GCRYCTL_SET_THREAD_CBS.
+ (gcry_thread_cbs): New struct.
+ * global.c (gcry_control): Implement GCRYCTL_SET_THREAD_CBS.
+ (global_init): Don't call ath_init here.
+ * ath.h: Rewritten.
+ * ath.c: Rewritten.
+
+2004-03-06 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: s/--soname-number/--api-version/
+ * libgcrypt.m4: Changed test for API version.
+
+2004-03-05 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.m4: Optionally check the SONAME number.
+
+ * libgcrypt-config.in: Add option --soname-number
+
+2004-03-01 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Add ath.c.
+ * ath.c (ath_init): Add missing function.
+
+ * Makefile.am (ath_pth_src): Removed.
+ (ath_pthread_src): Removed.
+ (libgcrypt_la_SOURCES): Remove ath-compat, $(ath_pth_src) and
+ $(ath_pthread_src).
+ * ath-compat.c, ath-pth-compat.c, ath-pthread-compat.c: Files
+ removed.
+
+2004-02-20 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_PRIME_CHECK_AT_GOT_PRIME)
+ (GCRY_PRIME_CHECK_AT_FINISH),
+ (GCRY_PRIME_CHECK_AT_MAYBE_PRIME): New.
+
+2004-02-18 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: Ignore setting of --prefix.
+
+2004-02-13 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRY_CIPHER_RFC2268_128, alsthough not yet
+ supported.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRY_CIPHER_RFC2268_40.
+
+2004-02-03 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_init): Do not print the "not locked into
+ core warning" if the NO_WARNING flag has been set.
+
+ * sexp.c (sexp_sscan): Allocate result in secure memory if BUFFER
+ is in secure memory. Switch to secure memory for the a secure %b
+ format item. Extra paranoid wipe on error.
+ (gcry_sexp_release): Added paranoid wiping for securely allocated
+ S-expressions.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * ath.h: Include <config.h>.
+
+2004-01-12 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h: Adjusted declarations of: gcry_ac_data_set,
+ gcry_ac_data_get_name, gcry_ac_data_get_index,
+ gcry_ac_key_pair_generate, gcry_ac_key_test,
+ gcry_ac_key_get_nbits, gcry_ac_key_get_grip.
+
+ * gcrypt.h (GCRY_AC_FLAG_DATA_NO_BLINDING): Removed symbol.
+ (GCRY_AC_FLAG_DEALLOC, GCRY_AC_FLAG_COPY)
+ (GCRY_AC_FLAG_NO_BLINDING): New symbols.
+
+ * global.c (gcry_strdup): Removed function.
+ * string.c: New file.
+ * Makefile.am (libgcrypt_real_la_SOURCES): Added: string.c.
+ * string.c (gcry_strdup): New function.
+ * gcrypt.h (gcry_strdup): Declare.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * g10lib.h (wipememory, wipememory2): New; taken from gnupg.
+
+2003-11-14 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strdup): Don't copy the string after a malloc
+ error.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Implemented "%b" format specifier.
+
+2003-11-11 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt.m4: Do not set prefix when calling libgcrypt-config.
+ Thanks to Nikos Mavroyanopoulos.
+
+2003-11-08 Moritz Schulte <mo@g10code.com>
+
+ * cipher.h (small_prime_numbers): Removed declaration.
+ (PUBKEY_FLAG_NO_BLINDING): Put braces around shift.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * cipher.h (_gcry_sha1_has_buffer): New.
+
+ * gcrypt.h (gcry_create_nonce): New.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.vers (_gcry_generate_elg_prime): Removed this symbol;
+ gnutls does not need it anymore.
+
+ * secmem.c (mb_get_new): s/pool/block/ due to global pool.
+
+ * misc.c (gcry_set_log_handler): s/logf/f/ to avoid shadowing
+ warning against a builtin.
+
+ * ath-pth-compat.c: cast pth_connect to get rid of the const
+ prototype.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * ath.h (ATH_MUTEX_INITIALIZER): Removed spurious semicolon.
+
+2003-10-27 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt-config.in: Include libs/cflags of libgpg-error.
+
+ * sexp.c (sexp_sscan): Cleaned up, deallocate scanned sexp on
+ error.
+
+ * module.c (MODULE_ID_MIN): New symbol, use it.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_pk_testkey): Doc fix.
+
+2003-09-29 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt-config.in: Fix --algorithms option.
+
+2003-10-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_err_code): Use GPG_ERR_INLINE instead of
+ __inline__.
+
+ * secmem.c (lock_pool): Don't print the warning for certain
+ systems, handle ENOMEM.
+
+2003-10-21 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_dump_stats): Fixed format sepcifier for a
+ size_t. Reported by Stephane Corthesy.
+
+2003-10-10 Werner Koch <wk@gnupg.org>
+
+ * global.c (_gcry_malloc): Handle the no_secure_memory option.
+
+ * gcrypt.h (gcry_prime_group_generator): New.
+ (gcry_prime_release_factors): New.
+
+2003-10-07 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Check that parenthesis are matching.
+
+2003-09-28 Moritz Schulte <mo@g10code.com>
+
+ * g10lib.h: Declare: _gcry_malloc.
+ (GCRY_ALLOC_FLAG_SECURE): New symbol.
+
+ * global.c (_gcry_malloc): New function...
+ (gcry_malloc): ... use it.
+ (gcry_malloc_secure): Likewise.
+
+ * ath.c: Change License to LGPL.
+ * ath-pthread-compat.c: Likewise.
+ * ath-pthread.c: Likewise.
+ * ath-pth-compat.c: Likewise.
+ * ath-pth.c: Likewise.
+ * ath.h: Likewise.
+ * ath-compat.c: Likewise.
+
+ * secmem.c (_gcry_secmem_realloc): Do not forget to release secmem
+ lock. Thanks to low halo for triggering this bug.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (_GCRY_ERR_SOURCE_DEFAULT): Removed cruft.
+ (gcry_prime_check_func_t): Renamed arg for clarity.
+
+2003-09-02 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h (GCRY_PRIME_FLAG_SPECIAL_FACTOR): New symbol.
+
+2003-09-01 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h (gcry_random_level_t): New type.
+ (gcry_prime_check_func_t): Likewise.
+ (GCRY_PRIME_FLAG_SECRET): New symbol.
+ (gcry_prime_generate, gcry_prime_check): Declare functions.
+
+2003-08-28 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (libgcrypt_pth_la_LDFLAGS): Removed PTH_CFLAGS cruft.
+
+2003-08-27 Moritz Schulte <mo@g10code.com>
+
+ * global.c (gcry_control): Remove call to ath_deinit.
+
+ * Makefile.am (libgcrypt_real_la_DEPENDENCIES): Fixed.
+ (libgcrypt_real_la_LIBADD): Fixed.
+ Removed unecessary variables.
+
+ * libgcrypt-config.in: Adjusted script for new thread handling.
+
+ * Makefile.am: New version, based on GPGMEs Makefile.am.
+
+ * ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c,
+ ath-pthread.c, ath-pthread-compat.c: New files, merged from GPGME.
+ * ath.c, ath.h, ath-pthread.c, ath-pth.c: Removed files.
+
+2003-08-08 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_realloc): Remove FIXME about `clearing out
+ realloced memory', since _gcry_secmem_realloc takes care of
+ overwriting old memory.
+
+2003-08-07 Werner Koch <wk@gnupg.org>
+
+ * module.c (_gcry_module_release): Don't act if module is NULL.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_ac_id): Added: GCRY_AC_ELG_E.
+ Reverted change: use gcry_md_flags enumeration list instead of
+ defines.
+
+2003-07-29 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_control): Add GCRYCTL_SET_RANDOM_SEED_FILE and
+ GCRYCTL_UPDATE_RANDOM_SEED_FILE.
+ * gcrypt.h: Ditto. Renamed index to idx, so avoid warning
+ related to the old index function.
+
+2003-07-28 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_err_code_from_errno, gcry_err_code_to_errno)
+ (gcry_err_make_from_errno, gcry_error_from_errno): New functions.
+
+ * gcrypt.h: Declared: gcry_err_code_from_errno,
+ gcry_err_code_to_errno, gcry_err_make_from_errno,
+ gcry_error_from_errno.
+
+ * Makefile.am (include_HEADERS): Added: gcrypt-module.h.
+
+ * gcrypt.h: Include <gcrypt-module.h>.
+
+ * gcrypt-module.h: New file.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_mpi_scan, gcry_mpi_print): API change.
+ (gcry_mpi_dump): New.
+
+2003-07-21 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declared: gcry_ac_key_data_get.
+ (gcry_pk_spec): Renamed member `sexp_names' into `aliases'.
+
+2003-07-20 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_md_oid_spec_t): New type.
+ (gcry_md_spec): New member: oids.
+
+2003-07-19 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_oid_spec_t): New type.
+ (gcry_cipher_spec): New member: oids;
+
+2003-07-18 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_mpi_set_opaque): Add a warning comment.
+
+2003-07-15 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (compress_pool): Remove function, since unused blocks
+ are automatically concatenad.
+
+ * gcrypt.h: Bumped version number up to 1.1.42-cvs.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_spec): New member: aliases.
+
+ * Makefile.am (noinst_PROGRAMS, testapi_SOURCES, testapai_LDADD,
+ benchmark_SOURCES, benchmark_LDADD): Removed.
+
+ * benchmark.c, testapi.c: Removed files.
+
+ * mpi.h: Removed disabled typedef.
+ * g10lib.h: Likewise.
+
+ * benchmark.c, g10lib.h, gcrypt.h, global.c, module.c, sexp.c:
+ Used gcry_err* wrappers for libgpg-error symbols.
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Likewise.
+
+ * gcrypt.h: New type: gcry_error_t, gcry_err_code_t and
+ gcry_err_source_t.
+ (gcry_err_make, gcry_error, gcry_err_code, gcry_err_source): New
+ functions.
+
+ * global.c (gcry_strerror): New function.
+ (gcry_strsource): New function.
+
+ * gcrypt.h: New symbol: GCRY_CIPHER_TWOFISH128.
+
+2003-07-09 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_md_flags): Removed, used define instead,
+ since that is more common than an enumeration list when it comes
+ to flags that can be bitwise ORed.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Use new types for handlers.
+
+ * gcrypt.h: Declare: gcry_ac_data_copy.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (gcry_sexp_build_array): Use dummy argument pointer.
+ Thanks to Simon Josefsson <jas@extunde.com>.
+
+ * gcrypt.h: Declare: gcry_cipher_list, gcry_pk_list, gcry_md_list.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declare: gcry_cipher_register, gcry_cipher_unregister,
+ gcry_md_register, gcry_md_unregister, gcry_pk_register,
+ gcry_pk_unregister.
+ (gcry_cipher_spec): Removed member: algorithm.
+ (gcry_pk_spec): Likewise.
+ (gcry_md_spec): Likewise.
+ Adjusted declarations: gcry_cipher_register, gcry_pk_register,
+ gcry_md_register.
+
+ * module.c: Replaced all occurences of `id' with `mod_id', since
+ `id' is a keyword in obj-c.
+
+ * gcrypt.h (gcry_cipher_spec): Renamed member `id' to `algorithm'.
+ (gcry_pk_spec): Likewise.
+ (gcry_md_spec): Likewise.
+
+ * cipher.h: Removed types: gcry_pubkey_generate_t,
+ gcry_pubkey_check_secret_key_t, gcry_pubkey_encrypt_t,
+ gcry_pubkey_decrypt_t, gcry_pubkey_sign_t, gcry_pubkey_verify_t,
+ gcry_pubkey_get_nbits_t, gcry_pk_spec_t, gcry_digest_init_t,
+ gcry_digest_write_t, gcry_digest_final_t, gcry_digest_read_t,
+ gcry_digest_spec_t, gcry_cipher_setkey_t, gcry_cipher_encrypt_t,
+ gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t,
+ gcry_cipher_stdecrypt_t, gcry_cipher_spec_t.
+
+ * gcrypt.h: New types: gcry_pk_generate_t,
+ gcry_pk_check_secret_key_t, gcry_pk_encrypt_t, gcry_pk_decrypt_t,
+ gcry_pk_sign_t, gcry_pk_verify_t, gcry_pk_get_nbits_t,
+ gcry_pk_spec_t, gcry_md_init_t, gcry_md_write_t, gcry_md_final_t,
+ gcry_md_read_t, gcry_md_spec_t, gcry_cipher_setkey_t,
+ gcry_cipher_encrypt_t, gcry_cipher_decrypt_t,
+ gcry_cipher_stencrypt_t, gcry_cipher_stdecrypt_t,
+ gcry_cipher_spec_t, gcry_module_t.
+
+2003-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_list): New function.
+
+2003-07-02 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_lookup): Fixed typo.
+
+ * gcrypt.h: Added all definitions and declarations necessary for
+ the new ac interface.
+
+2003-06-30 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h: Added declarations: _gcry_pk_module_lookup,
+ _gcry_pk_module_release.
+
+2003-06-18 Werner Koch <wk@gnupg.org>
+
+ * benchmark.c (cipher_bench): Adjusted for new API of get_blklen
+ and get_keylen.
+
+ * gcrypt.h (gcry_cipher_get_algo_blklen)
+ (gcry_cipher_get_algo_keylen): Replaced macro by funcion.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h: Renamed types GcryDigestSpec, GcryCipherSpec and
+ GcryPubkeySpec into: gcry_digest_spec_t, gcry_cipher_spec_t and
+ gcry_pubkey_spec_t.
+ (gcry_pubkey_spec): Defined member `id' as unsigned.
+ (gcry_digest_spec): Likewise.
+ (gcry_cipher_spec): Likewise.
+
+ * module.c (_gcry_module_id_new): New function.
+ (_gcry_module_add): Generate a new ID via _gcry_module_id_new in
+ case `id' is zero.
+
+ * g10lib.h, module.c: Replace old type GcryModule with newer one:
+ gcry_module_t.
+
+ * module.c (_gcry_module_add): Added argument `id', use it.
+
+ * g10lib.h: Added declaration: _gcry_module_lookup_id.
+ (_gcry_module_add): Added argument `id'.
+
+ * module.c (_gcry_module_lookup_id): New function.
+
+ * g10lib.h (struct gcry_module): New member: id.
+
+ * gcrypt.h: New type: gcry_handler_progress_t,
+ gcry_handler_alloc_t, gcry_haandler_secure_check_t,
+ gcry_handler_realloc_t, gcry_handler_free_t,
+ gcry_handler_no_mem_t, gcry_handler_error_t, gcry_handler_log_t.
+ Use new types.
+
+ * cipher.h: Include <gcrypt.h>.
+ New types: gcry_pk_generate_t, gcry_pk_check_secret_key_t,
+ gcry_pk_encrypt_t, gcry_pk_decrypt_t, gcry_pk_sign_t,
+ gcry_pk_verify_t, gcry_pk_get_nbits_t, gcry_md_init_t,
+ gcry_md_write_t, gcry_md_final_t, gcry_md_read_t,
+ gcry_cipher_setkey_t, gcry_cipher_encrypt_t,
+ gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t,
+ gcry_cipher_stdecrypt_t.
+ Use new types.
+
+2003-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * mpi.h: Likewise.
+ * sexp.c: Likewise.
+
+2003-06-15 Moritz Schulte <moritz@g10code.com>
+
+ * testapi.c (test_genkey): Use gpg_strerror instead of
+ gcry_strerror.
+
+ * global.c (gcry_control): Fixed typo.
+
+ * misc.c (_gcry_fatal_error): Use gpg_strerror instead of
+ gcry_strerror.
+
+ * types.h (STRLIST): Removed type since it is not used.
+
+2003-06-11 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (global_init): Call: _gcry_cipher_init, _gcry_md_init,
+ _gcry_pk_init.
+
+ * g10lib.h: Declare: _gcry_cipher_init, _gcry_md_init,
+ _gcry_pk_init.
+
+ * global.c (gcry_strerror): Remove compatibility code.
+
+ * Makefile.am: Remove support libgpg-error special handling.
+ (AM_CPPFLAGS): Add @GPG_ERROR_CFLAGS@
+
+ * gcrypt.h: Likewise.
+
+2003-06-13 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_md_get_algo): Reverted to old API. This is a
+ convenience function anyway and error checking is not approriate.
+ (gcry_md_is_enabled): New.
+ (gcry_md_is_secure): Replaced macro by function and reverted to old
+ API.
+
+2003-06-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYERR): Define _GCRY_ERR_SOURCE_DEFAULT instead of
+ GPG_ERR_SOURCE_DEFAULT, so that libgpg-error still works despite
+ the use of the old gcrypt error codes.
+ (gcry_md_copy): Swapped arguments.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Support for libgpg-error.
+
+2003-06-08 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (gcry_sexp_create): Expect sane error values from
+ gcry_sexp_canon_len instead of the `historical' values.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * ath.c, ath.c, ath-pth.c, ath-pthread.c, benchmark.c, cipher.h,
+ g10lib.h, gcrypt.h, global.c, misc.c, missing-string.c, module.c,
+ mpi.h, secmem.c, secmem.h, sexp.c, stdmem.c, stdmem.h, testapi.c,
+ types.h: Edited all preprocessor instructions to remove whitespace
+ before the '#'. This is not required by C89, but there are some
+ compilers out there that don't like it. Replaced any occurence of
+ the now deprecated type names with the new ones.
+
+ * gcrypt.h: Re-organized checking for gcc features; New macro:
+ _GCRY_GCC_ATTR_DEPRECATED.
+ Include copy of libgpg-error's gpg-error.h in order to make it
+ easy to build libgcrypt without needing libgpg-error.h.
+
+ (GCRY_MPI, GcryMPI, GCRY_SEXP, GcrySexp, GCRY_CIPHER_HD,
+ GcryCipherHd, GCRY_MD_HD, GcryMDHd): Declared deprecated.
+ (gcry_mpi_t, gcry_sexp_t, gcry_cipher_hd_t, gcry_md_hd_t): New
+ types.
+
+2003-06-04 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (sexp_sscan): New argument: arg_list, adjusted all
+ callers.
+ (ARG_NEXT): New macro.
+ (sexp_sscan): Use ARG_NEXT for receiving format string arguments.
+ (gcry_sexp_build_array): New function.
+
+2003-06-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Added some comments describing the gcry_sexp_*
+ functions.
+ Include <gpg-error.h> instead of <gpg/error.h>.
+
+2003-06-01 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (OLDPARSECODE): Removed macro...
+ (gcry_sexp_canon_len): ... and do not use it.
+
+ * gcrypt.h (gcry_errno): Removed declaration.
+
+ * g10lib.h (string_to_pubkey_algo, pubkey_algo_to_string,
+ pubkey_nbits): Removed declarations for non-existing functions.
+
+2003-05-31 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (is_RSA, is_ELGAMAL): Removed macros.
+
+ * g10lib.h (set_lasterr): Removed macro.
+ (_gcry_set_lasterr): Removed declaration.
+
+ * gcrypt.h: Changed declarations for: gcry_pk_algo_info,
+ gcry_md_open, gcry_md_copy, gcry_md_algo_info, gcry_md_info,
+ gcry_md_get_algo, gcry_random_add_bytes.
+
+ (gcry_md_is_secure): Adjust macro for new API.
+
+2003-05-29 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Changed declarations for: gcry_cipher_open,
+ gcry_cipher_info, gcry_cipher_algo_info.
+ (gcry_cipher_get_algo_keylen): Adjuster for new
+ gcry_cipher_algo_info interface.
+ (gcry_cipher_get_algo_blklen): Likewise.
+
+ * global.c (gcry_errno): Removed function.
+ (gcry_strerror): Do not use gcry_errno.
+ (_gcry_set_lasterr): Removed function.
+ (last_ec): Removed variable.
+
+2003-05-27 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_cipher_algos): Make Serpent IDs do not
+ conflict with OpenPGP. Reported by Timo Schulz.
+
+ * global.c (gcry_control): Fixed name of enum list.
+
+2003-05-25 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_cipher_spec): Adjust return type of `setkey' for
+ libgpg-error.
+ (gcry_pubkey_spec): Adjust return type of `generate',
+ `check_secret_key', `encrypt', `decrypt', `sign' and `verify' for
+ libgpg-error.
+
+ * sexp.c (gcry_sexp_canon_len): Adjusted for libgpg-error.
+ (gcry_sexp_create): Likewise.
+ (gcry_sexp_new): Likewise.
+ (sexp_sscan): Likewise.
+ (gcry_sexp_build): Likewise.
+ (gcry_sexp_sscan): Likewise.
+
+ * module.c (_gcry_module_add): Likewise.
+
+ * global.c (last_ec): Change type to gpg_error_t.
+ (gcry_control): Adjust for libgpg-error.
+ (gcry_errno): Likewise.
+ (gcry_strerror): Likewise.
+ (_gcry_set_lasterr): Likewise.
+ (gcry_xmalloc): Likewise.
+ (gcry_xrealloc): Likewise.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * types.h: Merged code from GnuPG regarding U64_C.
+
+ * missing-string.c (strsep): Removed function.
+
+ * g10lib.h: Removed declarations: strsep, strlwr.
+
+ * secmem.c (secmem_lock): New variable.
+ (SECMEM_LOCK, SECMEM_UNLOCK): New macros.
+ (_gcry_secmem_set_flags): Use SECMEM_LOCK and SECMEM_UNLOCK.
+ (_gcry_secmem_get_flags): Likewise.
+ (_gcry_secmem_init): Likewie.
+ (_gcry_secmem_malloc): Likewise.
+ (_gcry_secmem_free): Likewise.
+ (_gcry_secmem_malloc): Renamed to ...
+ (_gcry_secmem_malloc_internal): ... this.
+ (_gcry_secmem_malloc): New function, use SECMEM_LOCK,
+ SECMEM_UNLOCK, call _gcry_secmem_malloc_internal.
+ (_gcry_secmem_free): Renamed to ...
+ (_gcry_secmem_free_internal): ... this.
+ (_gcry_secmem_free): New function, use SECMEM_LOCK, SECMEM_UNLOCK,
+ call _gcry_secmem_free_internal.
+ (_gcry_secmem_realloc): Use SECMEM_LOCK, SECMEM_UNLOCK, call
+ _gcry_secmem_malloc_internal and _gcry_secmem_free_internal.
+ (_gcry_private_is_secure): Use SECMEM_LOCK, SECMEM_UNLOCK.
+ (_gcry_secmem_dump_stats): Likewise.
+ (_gcry_secmem_malloc_internal): Removed unused variable:
+ compressed.
+ Include "ath.h".
+
+2003-05-21 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (GCRY_CIPHER_SERPENT128, GCRY_CIPHER_SERPENT192,
+ GCRY_CIPHER_SERPENT256): New symbols.
+
+2003-05-19 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Reversed changes from 2003-03-03 since they would have
+ been an unnecessary ABI break.
+
+2003-05-13 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (stats_update): New function.
+ (BLOCK_HEAD_SIZE): New symbol.
+ (MB_FLAG_ACTIVE): New symbol.
+ (ADDR_TO_BLOCK, BLOCK_VALID): New macros.
+ (mb_get_next): New function.
+ (mb_get_prev): New function.
+ (mb_merge): New function.
+ (mb_get_new): New function.
+ (unused_blocks): Removed variable.
+ (init_pool): Initialize new memory pool.
+ (_gcry_secmem_malloc): Use new heap management code.
+ (_gcry_secmem_free): Likewise.
+ (_gcry_secmem_realloc): Likewise.
+ Renamed type MEMBLOCK to memblock_t.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_pubkey_spec): New member: sexp_names.
+
+2003-04-23 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_pubkey_spec): Removed members: npkey, nskey,
+ nenc, nsig.
+ (gcry_pubkey_spec): Added members: elements_pkey, elements_skey,
+ elements_enc, elements_sig, elements_grip.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h (GcryModule): New typedef.
+
+ * gcrypt.h (gcry_cipher_register, gcry_cipher_unregister,
+ gcry_digest_register, gcry_digest_unregister,
+ gcry_pubkey_register, gcry_pubkey_unregister): Function
+ declarations removed - for now.
+
+ * gcrypt.h (GcryModule): Declaration removed.
+ * gcrypt.h (GcryPubkeySpec, GcryDigestSpec, GcryCipherSpec):
+ Types Moved...
+ * cipher.h: ... here.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h: Declare digest_spec_sha512 and digest_spec_384.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_use): New function.
+ * g10lib.h (_gcry_module_use): Declare function.
+
+ * libgcrypt-config.in: Support for --algorithms switch, which
+ prints the algorithms included in the built libgcrypt.
+
+ * global.c (gcry_set_progress_handler): Register progress
+ functions depending on the enabled algorithms.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Added module.c
+
+ * module.c: New file.
+ (_gcry_module_add): New function.
+ (_gcry_module_drop): New function.
+ (_gcry_module_lookup): New function.
+ (_gcry_module_release): New function.
+
+ * g10lib.h (GcryModule): New types.
+ (FLAG_MODULE_DISABLED): New symbol.
+ Added declarations for _gcry_module_add, _gcry_module_release and
+ _gcry_module_lookup.
+
+ * gcrypt.h: New types: GcryPubkeySpec, GcryDigestSpec,
+ GcryCipherSpec.
+ Added declarations for: gcry_cipher_register,
+ gcry_cipher_unregister, gcry_digest_register,
+ gcry_digest_unregister, gcry_pubkey_register and
+ gcry_pubkey_unregister.
+
+ * cipher.h: Removed symbols: CIPHER_ALGO_NONE, CIPHER_ALGO_IDEA,
+ CIPHER_ALGO_3DES, CIPHER_ALGO_CAST5, CIPHER_ALGO_BLOWFISH,
+ CIPHER_ALGO_SAFER_SK128, CIPHER_ALGO_DES_SK, CIPHER_ALGO_TWOFISH,
+ CIPHER_ALGO_TWOFISH_OLD, CIPHER_ALGO_DUMMY, PUBKEY_USAGE_SIG,
+ PUBKEY_USAGE_ENC, DIGEST_ALGO_MD5, DIGEST_ALGO_SHA1,
+ DIGEST_ALGO_RMD160, DIGEST_ALGO_TIGER, PUBKEY_ALGO_RSA,
+ PUBKEY_ALGO_RSA_E, PUBKEY_ALGO_RSA_S, PUBKEY_ALGO_DSA,
+ PUBKEY_ALGO_ELGAMAL, PUBKEY_ALGO_ELGAMAL_E.
+
+2003-04-02 Moritz Schulte <moritz@g10code.com>
+
+ * benchmark.c (md_bench): Fix error message.
+
+2003-03-31 Moritz Schulte <moritz@g10code.com>
+
+ * benchmark.c (cipher_bench): Added CTR mode.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (enum gcry_control_cmds): Add GCRY_SET_CTR.
+ (enum gcry_cipher_modes): Add GCRY_CIPHER_MODE_CTR.
+ (gcry_cipher_setctr): New macro to set counter.
+
+2003-03-19 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (PUBKEY_FLAG_NO_BLINDING): New symbol.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h: Add GCRYCTL_SET_CBC_MAC and GCRY_CIPHER_CBC_MAC.
+
+2003-03-19 Werner Koch <wk@gnupg.org>
+
+ * g10lib.h: Adjusted primegen.c prototypes.
+
+2003-03-12 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Initialize NM. Thanks to Ian Peters for
+ valgrinding this.
+
+2003-03-06 Moritz Schulte <mo@g10code.com>
+
+ * secmem.h (GCRY_SECMEM_FLAG_NO_WARNING,
+ GCRY_SECMEM_FLAG_SUSPEND_WARNING): New symbols.
+
+ * global.c (gcry_control): Use
+ GCRY_SECMEM_FLAG_{NO,SUSPEND}_WARNING, instead of hard-coded
+ values.
+ * secmem.c (_gcry_secmem_set_flags): Likewise.
+ * secmem.c (_gcry_secmem_get_flags): Likewise.
+
+2003-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * misc.c: Removed old FIXME, since there is already a function to
+ set the value of `verbosity_level'.
+
+ * gcrypt.h: Removed enumeration list: gcry_ctl_cmds.
+ New enumeration lists: gcry_global_control_cmds,
+ gcry_control_cmds, gcry_info_cmds, gcry_algo_info_cmds.
+
+2003-03-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_reset): New macro for resetting a handle.
+
+2003-02-28 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (DEFAULT_PAGESIZE): New symbol.
+ (init_pool): Use DEFAULT_PAGESIZE.
+
+2003-02-23 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.h: Fix typo in declaration of _gcry_secmem_term.
+
+ * sexp.c: Move macro definitions of `digitp', `octdigit', `alphap'
+ and `hexdigit' ...
+ * g10lib.h: ... here.
+
+ * misc.c (_gcry_burn_stack): New function (former name:
+ burn_stack).
+
+ * g10lib.h (burn_stack): Declare _gcry_burn_stack().
+
+2003-01-24 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_set_progress_handler): Register a random progress
+ handler.
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_ENABLE_QUICK_RANDOM): New.
+ * global.c (gcry_control): Make use of it.
+
+2003-01-21 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_random_add_bytes): Add QUALITY argument.
+
+2003-01-21 Timo Schulz <twoaday@freakmail.de>
+
+ * gcrypt.h (gcry_random_add_bytes): New.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (gcry_md_algos): Add GCRY_MD_CRC32,
+ GCRY_MD_CRC32_RFC1510, GCRY_MD_CRC24_RFC2440.
+
+2003-01-16 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_md_write): Changed type of 2nd argument to void*.
+ (gcry_md_hash_buffer): Changed type of both buffers to void*.
+ (gcry_md_setkey): Changed type of 2nd argument to void*.
+ (gcry_md_get_asnoid): New.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_length): Fixed. This was seriously broken.
+
+2003-01-14 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYERR_INV_FLAG), global.c (gcry_strerror): New.
+
+2003-01-02 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.vers: Temporary export _gcry_generate_elg_prime for
+ use by GNUTLS.
+
+2002-12-21 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Make use of gcc's pure and malloc attributes
+ (gcry_md_putc): Use a helper variable to avoid multiple
+ evaluation of H.
+ * g10lib.h, stdmem.h, secmem.h: Use gcc attributes pure and malloc.
+
+ * stdmem.c (use_m_guard): Don't default to yes.
+
+2002-12-19 Werner Koch <wk@gnupg.org>
+
+ * global.c (global_init): The meat was never run due to a faulty
+ check. Thanks to Nikos for pointing this out.
+
+ * global.c (gcry_control): Return 1 and not -1 for the
+ initialization tests.
+
+ * libgcrypt.vers: New.
+ * Makefile.am: Use this instead of the build symbol file.
+
+ * global.c (gcry_control) <initialization>: Call the random module
+ initializer to make sure that the pool lock flag has been
+ initialized.
+
+2002-12-09 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_calloc,gcry_calloc_secure): Check for overflow.
+ Noted by Florian Weimer.
+
+2002-11-10 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (gcry_ctl_cmds): New GCRYCTL_SET_CBC_CTS control flag.
+ (gcry_cipher_flags): New GCRY_CIPHER_CBC_CTS gcry_cipher_open() flag.
+ (gcry_cipher_cts): New macro for toggling CTS.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_MD_MD4): New. We use a non OpenPGP value here.
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ * ath.c: Include sys.time.h if sys/select.h does not exist.
+ (ath_select, ath_waitpid): Shortcut for Windows.
+ * ath.h: Include some Windows headers. By Timo.
+
+2002-09-18 Werner Koch <wk@gnupg.org>
+
+ * ath.h: Prefix ath_deinit.
+
+2002-09-17 Werner Koch <wk@gnupg.org>
+
+ * benchmark.c: New.
+ (mpi_bench, do_powm): Add a a simple test for RSA.
+
+ * global.c (global_init): New. Use it instead of the setting
+ any_init_done. Initialize the ATH system.
+ (gcry_check_version): Hook global_init in. This is the suggested
+ way to initialize the library.
+ (_gcry_no_internal_locking): Removed. We simply call a ath_deinit
+ and leave it to ATH to disbale the locking.
+
+ * ath.c, ath.h, ath-pth.c, ath-pthread.c: New. Taken from GPGME.
+ * mutex.h: Removed.
+ * Makefile.am (ath_components): New.
+
+2002-09-16 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_dump_stats): Replaced fprintf by log_*.
+
+2002-08-23 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: Removed unneeded strlwr.
+
+ * libgcrypt.m4: Made much more simple.
+ * libgcrypt-config.in: Made --prefix work for --libs.
+
+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Add GCRY_CIPGER_DES. Included string.h for size_t.
+ Suggested by Simon Josefsson.
+
+2002-07-25 Werner Koch <wk@gnupg.org>
+
+ * cipher.h: Added prototypes for progress functions.
+ * global.c: Include cipher.h for those prototypes.
+
+ * stdmem.c (_gcry_private_realloc): Replaced void* by char * for
+ pointer arithmetic reasons. Noted by Stephan Austermuehle.
+
+2002-06-24 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: Include ctype.h.
+
+ * gcrypt.h (gcry_mpi_invm, gcry_mpi_div, gcry_mpi_mod)
+ (gcry_mpi_swap): New.
+
+2002-06-18 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added a bunch of brief function descriptions.
+
+2002-05-21 Werner Koch <wk@gnupg.org>
+
+ * misc.c (_gcry_log_printf): Don't initialize a va_list. Noted by
+ Jeff Johnson.
+
+ * global.c (gcry_set_progress_handler): New.
+
+ * gcrypt.h: Replaced the typedef for byte.
+
+2002-05-16 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: New.
+
+ * gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs
+ GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old
+ ones using an underscore.
+
+ * global.c (gcry_strerror): Add strings fro the new error codes.
+ * sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to
+ old error codes.
+ (gcry_sexp_create,gcry_sexp_new): New.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * mutex.h (DEFINE_LOCAL_MUTEX): Macro to define a mutex and
+ initialize it so that we can detect an unitialized mutex and don't
+ read from stdin.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of all files to the LGPL.
+
+2002-05-07 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_control): Add commands
+ GCRYCTL_ANY_INITIALIZATION_P and GCRYCTL_INITIALIZATION_FINISHED_P
+ so that other libraries are able to check for required
+ initializations.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYCTL_DISABLE_INTERNAL_LOCKING): New.
+ * global.c (gcry_control): Implement it.
+ (_gcry_no_internal_locking): New.
+ * mutex.h: Prefixed all fucntions with _gcry_. Bypass all
+ functions when desired.
+
+ * gcrypt.h (GCRYCTL_DISABLE_SECMEM): New.
+ * global.c (gcry_control,gcry_malloc_secure,gcry_is_secure):
+ Implement it here.
+ * secmem.c (_gcry_private_is_secure): Return false if the pool is
+ not initialized.
+
+ * gcrypt.h (GCRYCTL_INITIALIZATION_FINISHED): New.
+
+ * gcrypt.h (gcry_cipher_algos): Replaced RINDAEL by AES and change
+ the macros to expand from rijdael to aes.
+
+ * stdmem.c (_gcry_private_malloc): Return NULL for 0 byte allocation.
+ (_gcry_private_malloc_secure): Ditto.
+
+ * g10lib.h: Copied the JNLIB_GCC macros from ../jnlib/mischelp.h
+ and removed the inclusion of that file.
+
+2002-04-15 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strdup): New.
+
+2002-03-18 Werner Koch <wk@gnupg.org>
+
+ * mutex.h: New file with a portable thread mutex implementation
+ written by Marcus Brinkmann. Taken from GPGME.
+
+2002-02-18 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_sscan): Don't initialize the dummy
+ variable. Suggested by Jordi Mallach.
+
+2002-01-31 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (suitable_encoding,convert_to_hex,convert_to_string)
+ (convert_to_token): New.
+ (gcry_sexp_sprint): Better formatting of advanced encoding, does
+ now insert LFs and escapes all unprintable characters.
+ (unquote_string): New.
+ (sexp_sscan): Implemented the missing conversion of quoted strings.
+
+2002-01-26 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: Add copyright notice.
+
+2002-01-11 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Fixed last change.
+
+2002-01-01 Timo Schulz <ts@winpt.org>
+
+ * stdmem.c (_gcry_private_realloc): If pointer is NULL now realloc
+ behaves like malloc.
+
+2001-12-20 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Describe the error codes and
+ return an error if this is not a S-Exp; i.e. it does not start
+ with an open parenthesis.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Fixed the test on NULL buffer.
+
+ * Makefile.am (DISTCLEANFILES): Include libgcrypt.sym
+
+ * sexp.c: Removed the commented test code because we now have a
+ test in ../tests/
+
+2001-12-17 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): New.
+
+2001-12-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Fixed AES128 macro, add enum for OFB mode.
+
+2001-12-05 Werner Koch <wk@gnupg.org>
+
+ * misc.c (_gcry_log_printf): New.
+ * sexp.c (dump_string,gcry_sexp_dump): Use logging functions
+ instead of stderr.
+
+2001-11-16 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: New constant GCRYCTL_IS_ALGO_ENABLED.
+
+2001-10-02 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Removed a couple of trailing commas.
+
+2001-08-28 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Add an argument to enable the
+ arg_ptr. Changed all callers. Suggested by Tom Holroyd.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strerror): Updated list of error codes.
+
+2001-07-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Replaced the last ulong. Noted by Rami Lehti.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h, mpi.h: Made some mpi functions public.
+
+ * wrapper.c: Removed.
+ * global.c: Renamed all g10_ prefixed functions which had wrappers
+ to gcry_xxx. So we now use the exported memory functions inernally.
+
+ Renamed all g10_ prefixed functions to _gcry_ prefixed ones.
+
+ * g10lib.h (_GCRYPT_IN_LIBGCRYPT): Replace defintion by a test on it.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.m4: Check GCRYPT_VERSION macro and not LIBGCRYPT_VERSION.
+
+ * mpi.h: Removed mpi_fromstr prototype.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Add mpi.h
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ * types.h: Moved from ../include to here.
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * mpi.h: Moved to ../mpi.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-11 Werner Koch <wk@gnupg.org>
+
+ * mpi.h: Changed the way mpi_limb_t is defined.
+
+2000-10-10 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am: Take version-info from configure.
+
+2000-10-09 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: New cipher mode, new algo Arcfour and new error code
+ GCRYERR_INV_CIPHER_MODE.
+ * global.c (gcry_strerror): New errorcode.
+
+Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
+
+ * gcrypt.h (gcry_md_setkey): Replaced macro by function prototype.
+
+Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
+
+ * gcrypt.h (GCRYCTL_GET_ALGO_USAGE): New.
+
+ * secmem.c (secmem_realloc): check for failed secmem_malloc. By
+ Matt Kraai.
+
+Mon Jul 31 10:04:47 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c: Removed the datalen fields from list tags.
+ (gcry_sexp_car_data,gcry_sexp_cdr_data,gcry_sexp_car_mpi,
+ gcry_sexp_cdr_mpi): Removed.
+ (gcry_sexp_nth,gcry_sexp_nth_data,gcry_sexp_nth_mpi): New.
+
+Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c (sexp_sscan): Fixed reallocation to secure memory.
+ (new_empty_list): Removed
+ (gcry_sexp_length): New.
+ (gcry_sexp_enum): Removed.
+ (normalize): New. Reworked the whole thing to use NULL for an empty list.
+ (make_space): New instead of the macro.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c: Major rewrite.
+ (gcry_sexp_sscan): Reordered arguments. Moved functionality to ..
+ (sexp_sscan): .. this.
+ (gcry_sexp_build): New.
+ (gcry_sexp_new_name_mpi, gcry_sexp_new_name_data, gcry_sexp_new_data,
+ gcry_sexp_new_mpi): Removed.
+
+Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
+
+ * gcrypt.h (gcry_md_start_debug, gcry_md_stop_debug): New.
+ (gcry_ctl_cmds): New control values
+
+ * sexp.c (gcry_sexp_sscan): Add hex format parsing.
+
+ * secmem.c (lock_pool): Check for ENOSYS return my mlock() on old SCOs.
+ (pool_is_mmapped): Made volatile.
+ (lock_pool): No more warning for QNX. By Sam Roberts.
+ (lock_pool,secmem_init): Additional check for dropped privs.
+
+2000-03-21 09:18:48 Werner Koch (wk@habibti.gnupg.de)
+
+ * gcrypt.h (gcry_md_setkey): New.
+ (GCRY_MD_FLAG_HMAC): New.
+
+Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * Makefile.am: Add g10lib.h
+
+Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (gcry_sexp_sscan): Allow NULL for erroff.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (gcry_sexp_alist): New.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * secmem.c: Moved from ../util to here.
+ * secmem.h: New.
+ * stdmem.c: New. Based on the old ../util/memory.c.
+ * stdmem.h: New.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * gcrypt.m4: New.
+ * gcrypt-config: New.
+
+ * mpi.h (mpi_get_nbit_info): Removed
+ (mpi_set_nbit_info): Removed.
+ (struct gcry_mpi): Removed the nbits field.
+
+ * misc.c (g10_log_verbosity): New.
+
+ * global.c (g10_xstrdup): New.
+
+ * mpiapi.c: Removed.
+
+ * mpi.h: Moved from ../include to here. Removed some obsolete
+ prototypes and the iobuf.h header.
+ * cipher.h: Moved from ../include to here. Removed the mpi.h header.
+ * g10lib.h: Moved from ../include to here.
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (dump_string): New. Taken from gnupg/util/miscutil.c.
+ (do_dump_list): s/print_string/dump_string/.
+
+ * testapi.c: New.
+
+ * mpiapi.c (gcry_mpi_randomize): Use new random API.
+
+Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * gloabl.c (gcry_control): Add cases for dumping random
+ and secmem stats.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * pkapi.c: Removed.
+
+ * symapi.c: Removed.
+
+ * g10lib.h: Moved to ../include.
+
+ * mdapi.c: Removed.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * sexp.c: New.
+
+Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gcrypt.h: New
+ * mpiapi.c: New
+
+
+ Copyright (C) 1998,1999,2000,2001,2002,2003
+ 2004,2005,2008,2009,2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/grub-core/lib/libgcrypt/src/Makefile.am b/grub-core/lib/libgcrypt/src/Makefile.am
new file mode 100644
index 0000000..2a07067
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/Makefile.am
@@ -0,0 +1,143 @@
+# Makefile.am - for gcrypt/src
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+# 2006, 2007 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
+ gcrypt.h.in libgcrypt.def
+
+bin_SCRIPTS = libgcrypt-config
+m4datadir = $(datadir)/aclocal
+m4data_DATA = libgcrypt.m4
+include_HEADERS = gcrypt.h
+
+lib_LTLIBRARIES = libgcrypt.la
+bin_PROGRAMS = dumpsexp hmac256
+if USE_RANDOM_DAEMON
+sbin_PROGRAMS = gcryptrnd
+bin_PROGRAMS += getrandom
+endif USE_RANDOM_DAEMON
+
+# Depending on the architecture some targets require libgpg-error.
+if HAVE_W32CE_SYSTEM
+arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS)
+arch_gpg_error_libs = $(GPG_ERROR_LIBS)
+else
+arch_gpg_error_cflags =
+arch_gpg_error_libs =
+endif
+
+
+if HAVE_LD_VERSION_SCRIPT
+ libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers
+else
+ libgcrypt_version_script_cmd =
+endif
+
+libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
+libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \
+ cipher.h cipher-proto.h gcrypt-module.h \
+ misc.c global.c sexp.c hwfeatures.c \
+ stdmem.c stdmem.h secmem.c secmem.h \
+ mpi.h missing-string.c module.c fips.c \
+ hmac256.c hmac256.h \
+ ath.h ath.c
+
+if HAVE_W32_SYSTEM
+
+RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)
+LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
+
+SUFFIXES = .rc .lo
+
+.rc.lo:
+ $(LTRCCOMPILE) -i "$<" -o "$@"
+
+gcrypt_res = versioninfo.lo
+no_undefined = -no-undefined
+export_symbols = -export-symbols $(srcdir)/libgcrypt.def
+
+install-def-file:
+ $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def
+
+uninstall-def-file:
+ -rm $(DESTDIR)$(libdir)/libgcrypt.def
+
+gcrypt_deps = $(gcrypt_res) libgcrypt.def
+
+else !HAVE_W32_SYSTEM
+
+gcrypt_res =
+gcrypt_res_ldflag =
+no_undefined =
+export_symbols =
+install-def-file:
+uninstall-def-file:
+
+gcrypt_deps =
+
+endif !HAVE_W32_SYSTEM
+
+
+libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \
+ $(libgcrypt_version_script_cmd) -version-info \
+ @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
+libgcrypt_la_DEPENDENCIES = \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la \
+ $(srcdir)/libgcrypt.vers $(gcrypt_deps)
+libgcrypt_la_LIBADD = $(gcrypt_res) \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la $(GPG_ERROR_LIBS)
+
+
+dumpsexp_SOURCES = dumpsexp.c
+dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
+dumpsexp_LDADD = $(arch_gpg_error_libs)
+
+hmac256_SOURCES = hmac256.c
+hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
+hmac256_LDADD = $(arch_gpg_error_libs)
+
+if USE_RANDOM_DAEMON
+gcryptrnd_SOURCES = gcryptrnd.c
+gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
+gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
+
+getrandom_SOURCES = getrandom.c
+endif USE_RANDOM_DAEMON
+
+
+install-data-local: install-def-file
+
+uninstall-local: uninstall-def-file
+
+# FIXME: We need to figure out how to get the actual name (parsing
+# libgcrypt.la?) and how to create the hmac file already at link time
+# so that it can be used without installing libgcrypt first.
+#install-exec-hook:
+# ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \
+# < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \
+# > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac
diff --git a/grub-core/lib/libgcrypt/src/Manifest b/grub-core/lib/libgcrypt/src/Manifest
new file mode 100644
index 0000000..2d003d8
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/Manifest
@@ -0,0 +1,58 @@
+# Manifest - checksums of the src directory
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# Checksums for all source files in this directory. Format is
+# filename, blanks, base-64 part of an OpenPGP detached signature
+# without the header lines. Blank lines and lines beginning with a
+# hash mark are ignored. A tool to process this file is available by
+# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool
+#
+# The special entry "$names$" holds a signature over all sorted
+# filenames excluding itself.
+
+gcrypt.h iQCVAwUAQH5RsTEAnp832S/7AQK7xgP+Kc3NY9lipZkaAMrnHDkQVLdHYwTbZWuGOYdTLp8Xy7Auh9wtWV9hrWVUqs+kxDzT/2iF6XkO3WT3rf/PmQ/Q0TIGfOyjE3c/qvB/jVippaxoGda3tnGpODytdI3XPhfPS0Ss8nDzfCStPBGAEq0OVU7imnExrFzhRXt+Gljr0o0==Yagz
+gcrypt-module.h iQCVAwUAQH5UXzEAnp832S/7AQJMQgQAzumz9aaZelhw+FxTCeVadphBxt1bbNQvMrnddYYblyJv+AcxZ9ZxGz2oPeusN58Qg54DQcaW3lYhTgnWfXultsi+Ruxlz7400OUrzSXOl3At7KssdODAoscFzZIgh94G9lzQxEBr9lTXI9R3LsPFJP6muNG4frcNBAA42yckK7w==BBp5
+
+ath.c iQCVAwUAQH5E+DEAnp832S/7AQKFpgP+KSZHtVcnh9FFggIyHKbALUljW2FXauasZvFyN8Sk/mIMgKxyXFOG1THBAUzWLaKWIEWU+WkYU7uThqBtpnEImM5AenWzbQuJjftPC3gVHO8yjjmBWD4zmJj28htoKDoa/xDsoqumrHxae3FYcaCWtYGVjM/Pbl+OMRMOFAhp0ho==lQZ3
+ath.h iQCVAwUAQH5FODEAnp832S/7AQKiuQQAg4K+KOAn1LWBZN32MAhms4FeZKoce0fAuZW7BpyY4cCxIVgxqrtUC90CDykw8XegFfOyyYrgd0NmaMVdY7HZDncNOvIPxpgFQPCZrycsMOoAtoVwjK704RDeNo3zmeyxTKeDH+3M1J7JmLiafaEdSbOC8flX/W0icaV0Ol4dmBc==Ll6w
+
+cipher.h iQCVAwUAQH5FUzEAnp832S/7AQJKLgP9GSSk9f7EINIRqSQH1XKX+dYzt3phDHdqFTUGIfYNh7YzGdy0drvgFhG4k15nqDouKRuFVM/hKY3ZVY7JccmKXKGAH6+ZYShoG6LMFfIGgDX8zne0dNxc72PLfns3fVxNn/RlHmHBkrQ+ppjR9HnSthFmOqzbQaW1BKmc3Z2x5GU==lIeW
+g10lib.h iQCVAwUAQH5FejEAnp832S/7AQJ75wP/ZjOybwRix5eoXdfVeXPjoPygejzpYJJdMUGN3Y5UtkfBu9mPREsKfvZ6tH+Evjx+3xfeAb4bU/k2mRMp0tiWnk2koToS08vI9uxnioKQr9oulZH6r28S+NLSgMQuEGN1JNUky6RQ9TTNRndeTjKKSrEjZ7V6bv+rb8A1bYCKChs==P5mk
+mpi.h iQCVAwUAQH5FwzEAnp832S/7AQJJ4wP9E3jVkcO9M0YtSBHIbjG3hDWKWXzi86AlUh51qiE8/2XP0FfjA4TosyvmicZs7j48HitAByr9tHOSxnbeo7NBf17ICwAo6Eqty+wKDg+eyLeEGUy7VpVK3RJRQAA4H+kl3S2l3YMTKf3WJlbc7qkWSXZspdy5c9sAxeodCKrAubU==oALf
+
+global.c iQCVAwUAQH5HFzEAnp832S/7AQJc+QQAvi53ZkMCzLnVULHvhI6W+EX537zi9n8cplYguvIJqUhAZrP68yGAIyqyCONbZVDyB7wqeXdUMLzMk7W8fg+xuk5JSDpppAQf2m/bdQyze6XVqJso682eYBM8+b9z/IVEvLaFwhZcOKO1bcXudBlBCcJgVDpupfTtAWgPnewil9Q==Xwy1
+misc.c iQCVAwUAQH5IIjEAnp832S/7AQKNJAQAkEpyY3fCG7tvADJFAW9xA7DEQwLCa8YmiUhHvrEsWOI4YgvS7LUbWWc7VqK+ryORvXLKRAVieznbnHAuy0TKtqdnmA/kUmiurS0ah5SWqR/iuAeJtt0RGsmZaZ6oa2m4PZ2Y2GCHSTZqcclvwsetS9eq5AipxHxYFUltu5wGZNI==twM2
+missing-string.c iQCVAwUAQH5JfjEAnp832S/7AQI3ZQQAg55eEJbGQQHyBEJGxvt/FXpQiXcoDit3ZHzvdaQn/NUgdLjCHiWVzhyCXACGivLWMNModDaSaZk073NXxVkWfPcX9vkF//Wugwzidd5P3Bfu5k35o+Xxz82fsk5KuFGGq1mBUZ07xUYQ8KkKkhADUkr0QiQAuypp079Yq0uUC7Q==zvKn
+module.c iQCVAwUAQH5JvjEAnp832S/7AQKlMgQAjZYTXMpWb5kHxCMXzRi069Ku/4/xnWsD+S0dje1LiKzCnRpwTTxARzc/y10Y8OcygkMuR4unEaWedO+9syjjty3fBCcue/j7YlLitq5EC9UE4o23poWvWCuX9Tadm2DK5qf4p7smMJ22O22cLTYTVCyAoYTQ2xC8ajzBsBRkX80==yRRD
+secmem.c iQCVAwUAQH5LLDEAnp832S/7AQKtFwQAwY2wBr6WJC1cwqp/1DQoKzHx9C3plONxbZMazwR7VMI83NUbBAbv1mcxpeZWXmb2dRrnsR1VBbNPDSbJLN5T6czLQ2nIb6mnq9u8Ip4SAa+GCWfDV4AUtAJ4hN/yvWo8iEKu+KD5iJ6xJh31NdXjt5yk6vnk46SA6R4FkHdIEXc==UKVr
+secmem.h iQCVAwUAQH5LTDEAnp832S/7AQIsJwQAkZUu4hvmh9NXCLNm98+tGZFzWYvZO/NffC2wdPE8Q/OTa/m3g+oBbEhaV1ze3oY4t1F/p7ZHFx5CsIp4zVjyPkxlni8AAVMUOQr/LopyxouHn2OjKO+dVqecWQf01+nPWjklbL2FZ3mQ99k2qeWZlVSkz0nm8u39F3v7z3OTCss==AJqE
+sexp.c iQCVAwUAQH5LojEAnp832S/7AQKCTQQArlrj1KGwR2x93fcyN3M0iXuGkBq5R9KNu+1Bq04G4SLlpZ1RRY0OjV3L9To1BHTd01lXlO8MNz7NpRxWlG1Sw5FohbBlhWZQRcW8GdAawJPcfIY2Y8Ek6Yx8quZKbk9uD3bcBmStmg0P+TIA0nr20bmtfB3uX2KQVHQqWZQT5qU==P8FE
+stdmem.c iQCVAwUAQH5LzjEAnp832S/7AQLOUAP9FU16itXBBrkfRDGmhUjAOeEEKdd+brQ3XdT8xoLvP/IH/6U1Kq3ampP2/xcL4kwVdz2rw6NRzP7jlL/yM3tW722lSS/JPJkH+2+qUkcb0fYNoql/WYPMYp1/Mzu6ttXnjag1cQGlKIyYAD+G6h3FtpLwQy0hEJopnF9+Ovd8U7A==CkiZ
+stdmem.h iQCVAwUAQH5L8jEAnp832S/7AQIH0wP+Lyqh0tj++s2L79Tmf/gqgCK+HLMxTddcewF3XbsYf9T5FmLez1gz6Ggti4Ss9VjozOA3ti3trCiA/YNRmV9AYw4zLUPm+MsjJuveL/AgB9HdoD2v+RfJm0WwgSKiysp+8iyjg3Plopmhba4cGuOP5MJ3CWTqYwPmJVscUKC6g38==02MN
+
+types.h iQCVAwUAQH5MKTEAnp832S/7AQLqTAP6A3mUMD5MMkBkebq4bRY6Bq0KsgdKfZ8TLhc2o87gFay8YD0Uom3YJNG2LF/rAIct2ih4jYJaIb5dRfJ0KJoPi2ETd462J8OFCL4fjq9TaSjB2pXcB+kWoxzPasGNg2Ukk0dQ6lvF1tSYrtt32PVI7q/UaPsjTylgRmzLfX/VxrU==OMu3
+
+
+# Configuration
+Makefile.am iQCVAwUAQH5WVjEAnp832S/7AQLmsQP/bbI8/UWAC5yITVhGcCOCbN/FaMqXVKjxESzo6GTs02jxK1y3RuuaoNU1ssQZGAxpFiMJW8u933V3yTHFMxWpwHemDnEyv/a8YACxJBQ0tQgpgHS716BjMbHOfcuOis2WlCOOm0ErjhAYNa4NQ1q3jwkOvTDLFpdnqaWI2wWn08U==Yjun
+libgcrypt.m4 iQCVAwUAQH5MbTEAnp832S/7AQJ1uAQA1C6xI7qXiKVtUeXawhPytAldosrzcXmqz34xi7JklQqw83d68WtWHFMBEUa7MKfi4WCbuQb7FjGUvMRw5z/T9ez7CoDekHc63+cIIZLQ23weUK8GaA1uQLoD0scmT41J5RkBlJbH7ck1zRd3d04o75rWNEUNit6KBvrQ4Pd8oQ8==uMgB
+libgcrypt-config.in iQCVAwUAQH5UbzEAnp832S/7AQJISgP+Nbd2AQnDM/k8sQLbvz8YZjwX3LigZM+AkF1VAwyAm6YOU3nrXnz5t+cXkQD2dkz4L2F0AAsIkFiJsrgmZgCp2h1L6LeFnH+hoId9RhbYw4NkDaHb+MC9JcalpcfFvvxq6vM/W37bSFimM78P+5RLKypXCytVQNAAaIRgZjVfXY8==IGDS
+libgcrypt.vers iQCVAwUAQH5MjTEAnp832S/7AQKCdQQAotG6Z3zdcePI0V33YY2sh91uYkLBNhQw+PzyE3BRRAVhMGLOBD1nSWJHJvE3eyCVOqFY0ZmvpVex51Fa0D/TwsJOO4RVxf1L9bbAncu9OuEXaGXKytLZp54TliDTAWGDq0lvtx1TvDDgtM8TbbaXvMbjfQ4wXBxdLvaenFCTlR4==kgHq
+
+$names$ iQCVAwUAQH5UhDEAnp832S/7AQK/jwP9H7A3mI99M1NGuhD+16C+2gJIITB8GJeYeUd3vm8kWQ5n76WyMCdeA62qn0JUddIBjAbagtfvTL5aesnD9MlhEGaNlHauU7SINTIJ8njKf87EAAfDZrhS/tGDziC2nakMPweRxXQCLDWHkBPjYfrspSLLohjdegqBvTNyVM76+KE==3p9Z
diff --git a/grub-core/lib/libgcrypt/src/ath.c b/grub-core/lib/libgcrypt/src/ath.c
new file mode 100644
index 0000000..4834a52
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/ath.c
@@ -0,0 +1,323 @@
+/* ath.c - A Thread-safeness library.
+ * Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#if USE_POSIX_THREADS_WEAK
+# include <pthread.h>
+#endif
+
+#include "ath.h"
+
+
+
+/* On an ELF system it is easy to use pthreads using weak references.
+ Take care not to test the address of a weak referenced function we
+ actually use; some GCC versions have a bug were &foo != NULL is
+ always evaluated to true in PIC mode. USING_PTHREAD_AS_DEFAULT is
+ used by ath_install to detect the default usage of pthread. */
+#if USE_POSIX_THREADS_WEAK
+# pragma weak pthread_cancel
+# pragma weak pthread_mutex_init
+# pragma weak pthread_mutex_lock
+# pragma weak pthread_mutex_unlock
+# pragma weak pthread_mutex_destroy
+#endif
+
+/* For the dummy interface. The MUTEX_NOTINIT value is used to check
+ that a mutex has been initialized. Because its value is there is
+ no need to explicit initialized a mutex variable because it is
+ anyway static and we store a pointer to allocated memory there
+ after initialization. The same thing works with other thread
+ models. */
+#define MUTEX_NOTINIT ((ath_mutex_t) 0)
+#define MUTEX_UNLOCKED ((ath_mutex_t) 1)
+#define MUTEX_LOCKED ((ath_mutex_t) 2)
+#define MUTEX_DESTROYED ((ath_mutex_t) 3)
+
+
+/* Return the thread type from the option field. */
+#define GET_OPTION(a) ((a) & 0xff)
+
+
+
+enum ath_thread_model {
+ ath_model_undefined = 0,
+ ath_model_none, /* No thread support. */
+ ath_model_pthreads_weak, /* POSIX threads using weak symbols. */
+ ath_model_pthreads, /* POSIX threads directly linked. */
+ ath_model_w32 /* Microsoft Windows threads. */
+};
+
+
+/* The thread model in use. */
+static enum ath_thread_model thread_model;
+
+
+/* Initialize the ath subsystem. This is called as part of the
+ Libgcrypt initialization. It's purpose is to initialize the
+ locking system. It returns 0 on sucess or an ERRNO value on error.
+ In the latter case it is not defined whether ERRNO was changed.
+
+ Note: This should be called as early as possible because it is not
+ always possible to detect the thread model to use while already
+ running multi threaded. */
+int
+ath_init (void)
+{
+ int err = 0;
+
+ if (thread_model)
+ return 0; /* Already initialized - no error. */
+
+ if (0)
+ ;
+#if USE_POSIX_THREADS_WEAK
+ else if (pthread_cancel)
+ {
+ thread_model = ath_model_pthreads_weak;
+ }
+#endif
+ else
+ {
+ /* Assume a single threaded application. */
+ thread_model = ath_model_none;
+ }
+
+ return err;
+}
+
+
+/* Return the used thread model as string for display purposes an if
+ R_MODEL is not null store its internal number at R_MODEL. */
+const char *
+ath_get_model (int *r_model)
+{
+ if (r_model)
+ *r_model = thread_model;
+ switch (thread_model)
+ {
+ case ath_model_undefined: return "undefined";
+ case ath_model_none: return "none";
+ case ath_model_pthreads_weak: return "pthread(weak)";
+ case ath_model_pthreads: return "pthread";
+ case ath_model_w32: return "w32";
+ default: return "?";
+ }
+}
+
+
+/* This function was used in old Libgcrypt versions (via
+ GCRYCTL_SET_THREAD_CBS) to register the thread callback functions.
+ It is not anymore required. However to allow existing code to
+ continue to work, we keep this function and check that no user
+ defined callbacks are used and that the requested thread system
+ matches the one Libgcrypt is using. */
+gpg_err_code_t
+ath_install (struct ath_ops *ath_ops)
+{
+ unsigned int thread_option;
+
+ /* Check if the requested thread option is compatible to the
+ thread option we are already committed to. */
+ thread_option = ath_ops? GET_OPTION (ath_ops->option) : 0;
+
+ /* Return an error if the requested thread model does not match the
+ configured one. */
+ if (0)
+ ;
+#if USE_POSIX_THREADS_WEAK
+ else if (thread_model == ath_model_pthreads_weak)
+ {
+ if (thread_option == ATH_THREAD_OPTION_PTHREAD)
+ return 0; /* Okay - compatible. */
+ }
+#endif /*USE_POSIX_THREADS_WEAK*/
+ else if (thread_option == ATH_THREAD_OPTION_DEFAULT)
+ return 0; /* No thread support requested. */
+
+ return GPG_ERR_NOT_SUPPORTED;
+}
+
+
+/* Initialize a new mutex. This function returns 0 on success or an
+ system error code (i.e. an ERRNO value). ERRNO may or may not be
+ changed on error. */
+int
+ath_mutex_init (ath_mutex_t *lock)
+{
+ int err;
+
+ switch (thread_model)
+ {
+ case ath_model_none:
+ *lock = MUTEX_UNLOCKED;
+ err = 0;
+ break;
+
+#if USE_POSIX_THREADS_WEAK
+ case ath_model_pthreads_weak:
+ {
+ pthread_mutex_t *plck;
+
+ plck = malloc (sizeof *plck);
+ if (!plck)
+ err = errno? errno : ENOMEM;
+ else
+ {
+ err = pthread_mutex_init (plck, NULL);
+ if (err)
+ free (plck);
+ else
+ *lock = (void*)plck;
+ }
+ }
+ break;
+#endif /*USE_POSIX_THREADS_WEAK*/
+
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+
+/* Destroy a mutex. This function is a NOP if LOCK is NULL. If the
+ mutex is still locked it can't be destroyed and the function
+ returns EBUSY. ERRNO may or may not be changed on error. */
+int
+ath_mutex_destroy (ath_mutex_t *lock)
+{
+ int err;
+
+ if (!*lock)
+ return 0;
+
+ switch (thread_model)
+ {
+ case ath_model_none:
+ if (*lock != MUTEX_UNLOCKED)
+ err = EBUSY;
+ else
+ {
+ *lock = MUTEX_DESTROYED;
+ err = 0;
+ }
+ break;
+
+#if USE_POSIX_THREADS_WEAK
+ case ath_model_pthreads_weak:
+ {
+ pthread_mutex_t *plck = (pthread_mutex_t*)lock;
+
+ err = pthread_mutex_destroy (plck);
+ if (!err)
+ {
+ free (plck);
+ lock = NULL;
+ }
+ }
+ break;
+#endif /*USE_POSIX_THREADS_WEAK*/
+
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+
+/* Lock the mutex LOCK. On success the function returns 0; on error
+ an error code. ERRNO may or may not be changed on error. */
+int
+ath_mutex_lock (ath_mutex_t *lock)
+{
+ int err;
+
+ switch (thread_model)
+ {
+ case ath_model_none:
+ if (*lock == MUTEX_NOTINIT)
+ err = EINVAL;
+ else if (*lock == MUTEX_UNLOCKED)
+ {
+ *lock = MUTEX_LOCKED;
+ err = 0;
+ }
+ else
+ err = EDEADLK;
+ break;
+
+#if USE_POSIX_THREADS_WEAK
+ case ath_model_pthreads_weak:
+ err = pthread_mutex_lock ((pthread_mutex_t*)lock);
+ break;
+#endif /*USE_POSIX_THREADS_WEAK*/
+
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+/* Unlock the mutex LOCK. On success the function returns 0; on error
+ an error code. ERRNO may or may not be changed on error. */
+int
+ath_mutex_unlock (ath_mutex_t *lock)
+{
+ int err;
+
+ switch (thread_model)
+ {
+ case ath_model_none:
+ if (*lock == MUTEX_NOTINIT)
+ err = EINVAL;
+ else if (*lock == MUTEX_LOCKED)
+ {
+ *lock = MUTEX_UNLOCKED;
+ err = 0;
+ }
+ else
+ err = EPERM;
+ break;
+
+#if USE_POSIX_THREADS_WEAK
+ case ath_model_pthreads_weak:
+ err = pthread_mutex_unlock ((pthread_mutex_t*)lock);
+ break;
+#endif /*USE_POSIX_THREADS_WEAK*/
+
+ default:
+ err = EINVAL;
+ break;
+ }
+
+ return err;
+}
diff --git a/grub-core/lib/libgcrypt/src/ath.h b/grub-core/lib/libgcrypt/src/ath.h
new file mode 100644
index 0000000..6ffa928
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/ath.h
@@ -0,0 +1,92 @@
+/* ath.h - Thread-safeness library.
+ * Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ATH_H
+#define ATH_H
+
+#include <config.h>
+
+#ifdef _WIN32
+# include <windows.h>
+#else /* !_WIN32 */
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# else
+# include <sys/time.h>
+# endif
+# include <sys/types.h>
+# ifdef HAVE_SYS_MSG_H
+# include <sys/msg.h> /* (e.g. for zOS) */
+# endif
+# include <sys/socket.h>
+#endif /* !_WIN32 */
+#include <gpg-error.h>
+
+
+
+/* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols
+ a prefix. */
+#define _ATH_EXT_SYM_PREFIX _gcry_
+
+#ifdef _ATH_EXT_SYM_PREFIX
+#define _ATH_PREFIX1(x,y) x ## y
+#define _ATH_PREFIX2(x,y) _ATH_PREFIX1(x,y)
+#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x)
+#define ath_install _ATH_PREFIX(ath_install)
+#define ath_init _ATH_PREFIX(ath_init)
+#define ath_get_model _ATH_PREFIX(ath_get_model)
+#define ath_mutex_init _ATH_PREFIX(ath_mutex_init)
+#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
+#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
+#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
+#endif
+
+
+enum ath_thread_option
+ {
+ ATH_THREAD_OPTION_DEFAULT = 0,
+ ATH_THREAD_OPTION_USER = 1,
+ ATH_THREAD_OPTION_PTH = 2,
+ ATH_THREAD_OPTION_PTHREAD = 3
+ };
+
+struct ath_ops
+{
+ /* The OPTION field encodes the thread model and the version number
+ of this structure.
+ Bits 7 - 0 are used for the thread model
+ Bits 15 - 8 are used for the version number.
+ */
+ unsigned int option;
+
+};
+
+gpg_err_code_t ath_install (struct ath_ops *ath_ops);
+int ath_init (void);
+const char *ath_get_model (int *r_model);
+
+/* Functions for mutual exclusion. */
+typedef void *ath_mutex_t;
+
+int ath_mutex_init (ath_mutex_t *mutex);
+int ath_mutex_destroy (ath_mutex_t *mutex);
+int ath_mutex_lock (ath_mutex_t *mutex);
+int ath_mutex_unlock (ath_mutex_t *mutex);
+
+#endif /* ATH_H */
diff --git a/grub-core/lib/libgcrypt/src/cipher-proto.h b/grub-core/lib/libgcrypt/src/cipher-proto.h
new file mode 100644
index 0000000..347681f
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/cipher-proto.h
@@ -0,0 +1,124 @@
+/* cipher-proto.h - Internal declarations
+ * Copyright (C) 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file has been factored out from cipher.h so that it can be
+ used standalone in visibility.c . */
+
+#ifndef G10_CIPHER_PROTO_H
+#define G10_CIPHER_PROTO_H
+
+/* Definition of a function used to report selftest failures.
+ DOMAIN is a string describing the function block:
+ "cipher", "digest", "pubkey or "random",
+ ALGO is the algorithm under test,
+ WHAT is a string describing what has been tested,
+ DESC is a string describing the error. */
+typedef void (*selftest_report_func_t)(const char *domain,
+ int algo,
+ const char *what,
+ const char *errdesc);
+
+/* Definition of the selftest functions. */
+typedef gpg_err_code_t (*selftest_func_t)
+ (int algo, int extended, selftest_report_func_t report);
+
+
+/* An extended type of the generate function. */
+typedef gcry_err_code_t (*pk_ext_generate_t)
+ (int algo,
+ unsigned int nbits,
+ unsigned long evalue,
+ gcry_sexp_t genparms,
+ gcry_mpi_t *skey,
+ gcry_mpi_t **retfactors,
+ gcry_sexp_t *extrainfo);
+
+/* The type used to compute the keygrip. */
+typedef gpg_err_code_t (*pk_comp_keygrip_t)
+ (gcry_md_hd_t md, gcry_sexp_t keyparm);
+
+/* The type used to query ECC curve parameters. */
+typedef gcry_err_code_t (*pk_get_param_t)
+ (const char *name, gcry_mpi_t *pkey);
+
+/* The type used to query an ECC curve name. */
+typedef const char *(*pk_get_curve_t)(gcry_mpi_t *pkey, int iterator,
+ unsigned int *r_nbits);
+
+/* The type used to query ECC curve parameters by name. */
+typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name);
+
+/* The type used to convey additional information to a cipher. */
+typedef gpg_err_code_t (*cipher_set_extra_info_t)
+ (void *c, int what, const void *buffer, size_t buflen);
+
+
+/* Extra module specification structures. These are used for internal
+ modules which provide more functions than available through the
+ public algorithm register APIs. */
+typedef struct cipher_extra_spec
+{
+ selftest_func_t selftest;
+ cipher_set_extra_info_t set_extra_info;
+} cipher_extra_spec_t;
+
+typedef struct md_extra_spec
+{
+ selftest_func_t selftest;
+} md_extra_spec_t;
+
+typedef struct pk_extra_spec
+{
+ selftest_func_t selftest;
+ pk_ext_generate_t ext_generate;
+ pk_comp_keygrip_t comp_keygrip;
+ pk_get_param_t get_param;
+ pk_get_curve_t get_curve;
+ pk_get_curve_param_t get_curve_param;
+} pk_extra_spec_t;
+
+
+
+/* The private register functions. */
+gcry_error_t _gcry_cipher_register (gcry_cipher_spec_t *cipher,
+ cipher_extra_spec_t *extraspec,
+ int *algorithm_id,
+ gcry_module_t *module);
+gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher,
+ md_extra_spec_t *extraspec,
+ unsigned int *algorithm_id,
+ gcry_module_t *module);
+gcry_error_t _gcry_pk_register (gcry_pk_spec_t *cipher,
+ pk_extra_spec_t *extraspec,
+ unsigned int *algorithm_id,
+ gcry_module_t *module);
+
+/* The selftest functions. */
+gcry_error_t _gcry_cipher_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_md_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_pk_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_hmac_selftest (int algo, int extended,
+ selftest_report_func_t report);
+
+gcry_error_t _gcry_random_selftest (selftest_report_func_t report);
+
+#endif /*G10_CIPHER_PROTO_H*/
diff --git a/grub-core/lib/libgcrypt/src/cipher.h b/grub-core/lib/libgcrypt/src/cipher.h
new file mode 100644
index 0000000..0f923d7
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/cipher.h
@@ -0,0 +1,181 @@
+/* cipher.h
+ * Copyright (C) 1998, 2002, 2003, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_CIPHER_H
+#define G10_CIPHER_H
+
+#include <gcrypt.h>
+
+#define DBG_CIPHER _gcry_get_debug_flag( 1 )
+
+#include "../random/random.h"
+
+#define PUBKEY_FLAG_NO_BLINDING (1 << 0)
+
+enum pk_operation
+ {
+ PUBKEY_OP_ENCRYPT,
+ PUBKEY_OP_DECRYPT,
+ PUBKEY_OP_SIGN,
+ PUBKEY_OP_VERIFY
+ };
+
+enum pk_encoding
+ {
+ PUBKEY_ENC_RAW,
+ PUBKEY_ENC_PKCS1,
+ PUBKEY_ENC_OAEP,
+ PUBKEY_ENC_PSS,
+ PUBKEY_ENC_UNKNOWN
+ };
+
+struct pk_encoding_ctx
+{
+ enum pk_operation op;
+ unsigned int nbits;
+
+ enum pk_encoding encoding;
+ int flags;
+
+ int hash_algo;
+
+ /* for OAEP */
+ unsigned char *label;
+ size_t labellen;
+
+ /* for PSS */
+ size_t saltlen;
+
+ int (* verify_cmp) (void *opaque, gcry_mpi_t tmp);
+ void *verify_arg;
+};
+
+#define CIPHER_INFO_NO_WEAK_KEY 1
+
+#include "cipher-proto.h"
+
+
+/*-- rmd160.c --*/
+void _gcry_rmd160_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+/*-- sha1.c --*/
+void _gcry_sha1_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+
+/*-- rijndael.c --*/
+void _gcry_aes_cfb_enc (void *context, unsigned char *iv,
+ void *outbuf, const void *inbuf,
+ unsigned int nblocks);
+void _gcry_aes_cfb_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+void _gcry_aes_cbc_enc (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks, int cbc_mac);
+void _gcry_aes_cbc_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+void _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+
+
+/*-- dsa.c --*/
+void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data);
+
+/*-- elgamal.c --*/
+void _gcry_register_pk_elg_progress (gcry_handler_progress_t cb,
+ void *cb_data);
+
+
+/*-- ecc.c --*/
+void _gcry_register_pk_ecc_progress (gcry_handler_progress_t cbc,
+ void *cb_data);
+
+
+/*-- primegen.c --*/
+void _gcry_register_primegen_progress (gcry_handler_progress_t cb,
+ void *cb_data);
+
+/*-- pubkey.c --*/
+const char * _gcry_pk_aliased_algo_name (int algorithm);
+
+/* Declarations for the cipher specifications. */
+extern gcry_cipher_spec_t _gcry_cipher_spec_blowfish;
+extern gcry_cipher_spec_t _gcry_cipher_spec_des;
+extern gcry_cipher_spec_t _gcry_cipher_spec_tripledes;
+extern gcry_cipher_spec_t _gcry_cipher_spec_arcfour;
+extern gcry_cipher_spec_t _gcry_cipher_spec_cast5;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_twofish;
+extern gcry_cipher_spec_t _gcry_cipher_spec_twofish128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40;
+extern gcry_cipher_spec_t _gcry_cipher_spec_seed;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256;
+
+extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes192;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes256;
+
+
+/* Declarations for the digest specifications. */
+extern gcry_md_spec_t _gcry_digest_spec_crc32;
+extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510;
+extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440;
+extern gcry_md_spec_t _gcry_digest_spec_md4;
+extern gcry_md_spec_t _gcry_digest_spec_md5;
+extern gcry_md_spec_t _gcry_digest_spec_rmd160;
+extern gcry_md_spec_t _gcry_digest_spec_sha1;
+extern gcry_md_spec_t _gcry_digest_spec_sha224;
+extern gcry_md_spec_t _gcry_digest_spec_sha256;
+extern gcry_md_spec_t _gcry_digest_spec_sha512;
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
+extern gcry_md_spec_t _gcry_digest_spec_tiger;
+extern gcry_md_spec_t _gcry_digest_spec_tiger1;
+extern gcry_md_spec_t _gcry_digest_spec_tiger2;
+extern gcry_md_spec_t _gcry_digest_spec_whirlpool;
+
+extern md_extra_spec_t _gcry_digest_extraspec_sha1;
+extern md_extra_spec_t _gcry_digest_extraspec_sha224;
+extern md_extra_spec_t _gcry_digest_extraspec_sha256;
+extern md_extra_spec_t _gcry_digest_extraspec_sha384;
+extern md_extra_spec_t _gcry_digest_extraspec_sha512;
+
+/* Declarations for the pubkey cipher specifications. */
+extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_elg;
+extern gcry_pk_spec_t _gcry_pubkey_spec_dsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh;
+
+extern pk_extra_spec_t _gcry_pubkey_extraspec_rsa;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_elg;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa;
+
+
+#endif /*G10_CIPHER_H*/
diff --git a/grub-core/lib/libgcrypt/src/dumpsexp.c b/grub-core/lib/libgcrypt/src/dumpsexp.c
new file mode 100644
index 0000000..f6384d7
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/dumpsexp.c
@@ -0,0 +1,766 @@
+/* dumpsexp.c - Dump S-expressions.
+ * Copyright (C) 2007, 2010 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <errno.h>
+/* For a native WindowsCE binary we need to include gpg-error.h to
+ provide a replacement for strerror. */
+#ifdef __MINGW32CE__
+# include <gpg-error.h>
+#endif
+
+#define PGM "dumpsexp"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+
+static int verbose; /* Verbose mode. */
+static int decimal; /* Print addresses in decimal. */
+static int assume_hex; /* Assume input is hexencoded. */
+static int advanced; /* Advanced format output. */
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2010 Free Software Foundation, Inc.\n"
+ "License GPLv3+: GNU GPL version 3 or later "
+ "<http://gnu.org/licenses/gpl.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] [file]\n"
+ "Debug tool for S-expressions\n"
+ "\n"
+ " --decimal Print offsets using decimal notation\n"
+ " --assume-hex Assume input is a hex dump\n"
+ " --advanced Print file in advanced format\n"
+ " --verbose Show what we are doing\n"
+ " --version Print version of the program and exit\n"
+ " --help Display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+#define space_p(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
+#define digit_p(a) ((a) >= '0' && (a) <= '9')
+#define octdigit_p(a) ((a) >= '0' && (a) <= '7')
+#define alpha_p(a) ( ((a) >= 'A' && (a) <= 'Z') \
+ || ((a) >= 'a' && (a) <= 'z'))
+#define hexdigit_p(a) (digit_p (a) \
+ || ((a) >= 'A' && (a) <= 'F') \
+ || ((a) >= 'a' && (a) <= 'f'))
+#define xtoi_1(a) ((a) <= '9'? ((a)- '0'): \
+ (a) <= 'F'? ((a)-'A'+10):((a)-'a'+10))
+
+
+/* Return true if P points to a byte containing a whitespace according
+ to the S-expressions definition. */
+static inline int
+whitespace_p (int c)
+{
+ switch (c)
+ {
+ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
+ default: return 0;
+ }
+}
+
+static void
+logit (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ va_end (arg_ptr);
+}
+
+/* The raw data buffer and its current length */
+static unsigned char databuffer[16];
+static int databufferlen;
+/* The number of bytes in databuffer which should be skipped at a flush. */
+static int skipdatabufferlen;
+/* The number of raw bytes printed on the last line. */
+static int nbytesprinted;
+/* The file offset of the current data buffer . */
+static unsigned long databufferoffset;
+
+
+
+static int
+my_getc (FILE *fp)
+{
+ int c1, c2;
+
+ if (!assume_hex)
+ return getc (fp);
+
+ while ( (c1=getc (fp)) != EOF && space_p (c1) )
+ ;
+ if (c1 == EOF)
+ return EOF;
+
+ if (!hexdigit_p (c1))
+ {
+ logit ("non hex-digit encountered\n");
+ return EOF;
+ }
+
+ while ( (c2=getc (fp)) != EOF && space_p (c2) )
+ ;
+ if (c2 == EOF)
+ {
+ logit ("error reading second hex nibble\n");
+ return EOF;
+ }
+ if (!hexdigit_p (c2))
+ {
+ logit ("second hex nibble is not a hex-digit\n");
+ return EOF;
+ }
+ return xtoi_1 (c1) * 16 + xtoi_1 (c2);
+}
+
+
+
+
+
+/* Flush the raw data buffer. */
+static void
+flushdatabuffer (void)
+{
+ int i;
+
+ if (!databufferlen)
+ return;
+ nbytesprinted = 0;
+ if (decimal)
+ printf ("%08lu ", databufferoffset);
+ else
+ printf ("%08lx ", databufferoffset);
+ for (i=0; i < databufferlen; i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ if (i < skipdatabufferlen)
+ fputs (" ", stdout);
+ else
+ {
+ printf (" %02x", databuffer[i]);
+ databufferoffset++;
+ }
+ nbytesprinted++;
+ }
+ for (; i < sizeof (databuffer); i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ fputs (" ", stdout);
+ }
+ fputs (" |", stdout);
+ for (i=0; i < databufferlen; i++)
+ {
+ if (i < skipdatabufferlen)
+ putchar (' ');
+ else if (databuffer[i] >= ' ' && databuffer[i] <= '~'
+ && databuffer[i] != '|')
+ putchar (databuffer[i]);
+ else
+ putchar ('.');
+ }
+ putchar ('|');
+ putchar ('\n');
+ databufferlen = 0;
+ skipdatabufferlen = 0;
+}
+
+
+/* Add C to the raw data buffer and flush as needed. */
+static void
+addrawdata (int c)
+{
+ if ( databufferlen >= sizeof databuffer )
+ flushdatabuffer ();
+ databuffer[databufferlen++] = c;
+}
+
+
+static void
+printcursor (int both)
+{
+ int i;
+
+ flushdatabuffer ();
+ printf ("%8s ", "");
+ for (i=0; i < sizeof (databuffer); i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ if (i+1 == nbytesprinted)
+ {
+ fputs (" ^ ", stdout);
+ if (!both)
+ break;
+ }
+ else
+ fputs (" ", stdout);
+ }
+ if (both)
+ {
+ fputs (" ", stdout);
+ for (i=0; i < nbytesprinted-1; i++)
+ putchar (' ');
+ putchar ('^');
+ }
+ databufferlen = skipdatabufferlen = nbytesprinted;
+}
+
+static void
+printerr (const char *text)
+{
+ printcursor (1);
+ printf ("\n Error: %s\n", text);
+}
+
+static void
+printctl (const char *text)
+{
+ if (verbose && !advanced)
+ {
+ printcursor (0);
+ printf ("%s\n", text);
+ }
+}
+
+static void
+printchr (int c)
+{
+ putchar (c);
+}
+
+/* static void */
+/* printhex (int c) */
+/* { */
+/* printf ("\\x%02x", c); */
+/* } */
+
+
+#if 0
+/****************
+ * Print SEXP to buffer using the MODE. Returns the length of the
+ * SEXP in buffer or 0 if the buffer is too short (We have at least an
+ * empty list consisting of 2 bytes). If a buffer of NULL is provided,
+ * the required length is returned.
+ */
+size_t
+gcry_sexp_sprint (const gcry_sexp_t list,
+ void *buffer, size_t maxlength )
+{
+ static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
+ const unsigned char *s;
+ char *d;
+ DATALEN n;
+ char numbuf[20];
+ int i, indent = 0;
+
+ s = list? list->d : empty;
+ d = buffer;
+ while ( *s != ST_STOP )
+ {
+ switch ( *s )
+ {
+ case ST_OPEN:
+ s++;
+ if (indent)
+ putchar ('\n');
+ for (i=0; i < indent; i++)
+ putchar (' ');
+ putchar ('(');
+ indent++;
+ break;
+ case ST_CLOSE:
+ s++;
+ putchar (')');
+ indent--;
+ if (*s != ST_OPEN && *s != ST_STOP)
+ {
+ putchar ('\n');
+ for (i=0; i < indent; i++)
+ putchar (' ');
+ }
+ break;
+ case ST_DATA:
+ s++;
+ memcpy (&n, s, sizeof n);
+ s += sizeof n;
+ {
+ int type;
+ size_t nn;
+
+ switch ( (type=suitable_encoding (s, n)))
+ {
+ case 1: nn = convert_to_string (s, n, NULL); break;
+ case 2: nn = convert_to_token (s, n, NULL); break;
+ default: nn = convert_to_hex (s, n, NULL); break;
+ }
+ switch (type)
+ {
+ case 1: convert_to_string (s, n, d); break;
+ case 2: convert_to_token (s, n, d); break;
+ default: convert_to_hex (s, n, d); break;
+ }
+ d += nn;
+ if (s[n] != ST_CLOSE)
+ putchar (' ');
+ }
+ else
+ {
+ snprintf (numbuf, sizeof numbuf, "%u:", (unsigned int)n );
+ d = stpcpy (d, numbuf);
+ memcpy (d, s, n);
+ d += n;
+ }
+ s += n;
+ break;
+ default:
+ BUG ();
+ }
+ }
+ putchar ('\n');
+ return len;
+}
+#endif
+
+
+/* Prepare for saving a chunk of data. */
+static void
+init_data (void)
+{
+
+}
+
+/* Push C on the current data chunk. */
+static void
+push_data (int c)
+{
+ (void)c;
+}
+
+/* Flush and thus print the current data chunk. */
+static void
+flush_data (void)
+{
+
+}
+
+
+/* Returns 0 on success. */
+static int
+parse_and_print (FILE *fp)
+{
+ static const char tokenchars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-./_:*+=";
+ int c;
+ int level = 0;
+ int tokenc = 0;
+ int hexcount = 0;
+ int disphint = 0;
+ unsigned long datalen = 0;
+ char quote_buf[10];
+ int quote_idx = 0;
+ enum
+ {
+ INIT_STATE = 0, IN_NUMBER, PRE_DATA, IN_DATA, IN_STRING,
+ IN_ESCAPE, IN_OCT_ESC, IN_HEX_ESC,
+ CR_ESC, LF_ESC, IN_HEXFMT, IN_BASE64
+ }
+ state = INIT_STATE;
+
+
+ while ((c = my_getc (fp)) != EOF )
+ {
+ addrawdata (c);
+ switch (state)
+ {
+ case INIT_STATE:
+ if (tokenc)
+ {
+ if (strchr (tokenchars, c))
+ {
+ printchr (c);
+ continue;
+ }
+ tokenc = 0;
+ }
+ parse_init_state:
+ if (c == '(')
+ {
+ if (disphint)
+ {
+ printerr ("unmatched display hint");
+ disphint = 0;
+ }
+ printctl ("open");
+ level++;
+ }
+ else if (c == ')')
+ {
+ if (disphint)
+ {
+ printerr ("unmatched display hint");
+ disphint = 0;
+ }
+ printctl ("close");
+ level--;
+ }
+ else if (c == '\"')
+ {
+ state = IN_STRING;
+ printctl ("beginstring");
+ init_data ();
+ }
+ else if (c == '#')
+ {
+ state = IN_HEXFMT;
+ hexcount = 0;
+ printctl ("beginhex");
+ init_data ();
+ }
+ else if (c == '|')
+ {
+ state = IN_BASE64;
+ printctl ("beginbase64");
+ init_data ();
+ }
+ else if (c == '[')
+ {
+ if (disphint)
+ printerr ("nested display hint");
+ disphint = c;
+ }
+ else if (c == ']')
+ {
+ if (!disphint)
+ printerr ("no open display hint");
+ disphint = 0;
+ }
+ else if (c >= '0' && c <= '9')
+ {
+ if (c == '0')
+ printerr ("zero prefixed length");
+ state = IN_NUMBER;
+ datalen = (c - '0');
+ }
+ else if (strchr (tokenchars, c))
+ {
+ printchr (c);
+ tokenc = c;
+ }
+ else if (whitespace_p (c))
+ ;
+ else if (c == '{')
+ {
+ printerr ("rescanning is not supported");
+ }
+ else if (c == '&' || c == '\\')
+ {
+ printerr ("reserved punctuation detected");
+ }
+ else
+ {
+ printerr ("bad character detected");
+ }
+ break;
+
+ case IN_NUMBER:
+ if (digit_p (c))
+ {
+ unsigned long tmp = datalen * 10 + (c - '0');
+ if (tmp < datalen)
+ {
+ printerr ("overflow in data length");
+ state = INIT_STATE;
+ datalen = 0;
+ }
+ else
+ datalen = tmp;
+ }
+ else if (c == ':')
+ {
+ if (!datalen)
+ {
+ printerr ("no data length");
+ state = INIT_STATE;
+ }
+ else
+ state = PRE_DATA;
+ }
+ else if (c == '\"' || c == '#' || c == '|' )
+ {
+ /* We ignore the optional length and divert to the init
+ state parser code. */
+ goto parse_init_state;
+ }
+ else
+ printerr ("invalid length specification");
+ break;
+
+ case PRE_DATA:
+ state = IN_DATA;
+ printctl ("begindata");
+ init_data ();
+ case IN_DATA:
+ if (datalen)
+ {
+ push_data (c);
+ datalen--;
+ }
+ if (!datalen)
+ {
+ state = INIT_STATE;
+ printctl ("enddata");
+ flush_data ();
+ }
+ break;
+
+ case IN_STRING:
+ if (c == '\"')
+ {
+ printctl ("endstring");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else if (c == '\\')
+ state = IN_ESCAPE;
+ else
+ push_data (c);
+ break;
+
+ case IN_ESCAPE:
+ switch (c)
+ {
+ case 'b': push_data ('\b'); state = IN_STRING; break;
+ case 't': push_data ('\t'); state = IN_STRING; break;
+ case 'v': push_data ('\v'); state = IN_STRING; break;
+ case 'n': push_data ('\n'); state = IN_STRING; break;
+ case 'f': push_data ('\f'); state = IN_STRING; break;
+ case 'r': push_data ('\r'); state = IN_STRING; break;
+ case '"': push_data ('"'); state = IN_STRING; break;
+ case '\'': push_data ('\''); state = IN_STRING; break;
+ case '\\': push_data ('\\'); state = IN_STRING; break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ state = IN_OCT_ESC;
+ quote_idx = 0;
+ quote_buf[quote_idx++] = c;
+ break;
+
+ case 'x':
+ state = IN_HEX_ESC;
+ quote_idx = 0;
+ break;
+
+ case '\r':
+ state = CR_ESC;
+ break;
+
+ case '\n':
+ state = LF_ESC;
+ break;
+
+ default:
+ printerr ("invalid escape sequence");
+ state = IN_STRING;
+ break;
+ }
+ break;
+
+ case IN_OCT_ESC:
+ if (quote_idx < 3 && strchr ("01234567", c))
+ {
+ quote_buf[quote_idx++] = c;
+ if (quote_idx == 3)
+ {
+ push_data ((unsigned int)quote_buf[0] * 8 * 8
+ + (unsigned int)quote_buf[1] * 8
+ + (unsigned int)quote_buf[2]);
+ state = IN_STRING;
+ }
+ }
+ else
+ state = IN_STRING;
+ break;
+ case IN_HEX_ESC:
+ if (quote_idx < 2 && strchr ("0123456789abcdefABCDEF", c))
+ {
+ quote_buf[quote_idx++] = c;
+ if (quote_idx == 2)
+ {
+ push_data (xtoi_1 (quote_buf[0]) * 16
+ + xtoi_1 (quote_buf[1]));
+ state = IN_STRING;
+ }
+ }
+ else
+ state = IN_STRING;
+ break;
+ case CR_ESC:
+ state = IN_STRING;
+ break;
+ case LF_ESC:
+ state = IN_STRING;
+ break;
+
+ case IN_HEXFMT:
+ if (hexdigit_p (c))
+ {
+ push_data (c);
+ hexcount++;
+ }
+ else if (c == '#')
+ {
+ if ((hexcount & 1))
+ printerr ("odd number of hex digits");
+ printctl ("endhex");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else if (!whitespace_p (c))
+ printerr ("bad hex character");
+ break;
+
+ case IN_BASE64:
+ if (c == '|')
+ {
+ printctl ("endbase64");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else
+ push_data (c);
+ break;
+
+ default:
+ logit ("invalid state %d detected", state);
+ exit (1);
+ }
+ }
+ flushdatabuffer ();
+ if (ferror (fp))
+ {
+ logit ("error reading input: %s\n", strerror (errno));
+ return -1;
+ }
+ return 0;
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ int rc;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ argc--; argv++;
+ verbose = 1;
+ }
+ else if (!strcmp (*argv, "--decimal"))
+ {
+ argc--; argv++;
+ decimal = 1;
+ }
+ else if (!strcmp (*argv, "--assume-hex"))
+ {
+ argc--; argv++;
+ assume_hex = 1;
+ }
+ else if (!strcmp (*argv, "--advanced"))
+ {
+ argc--; argv++;
+ advanced = 1;
+ }
+ else
+ print_usage ();
+ }
+
+ if (!argc)
+ {
+ rc = parse_and_print (stdin);
+ }
+ else
+ {
+ rc = 0;
+ for (; argc; argv++, argc--)
+ {
+ FILE *fp = fopen (*argv, "rb");
+ if (!fp)
+ {
+ logit ("can't open `%s': %s\n", *argv, strerror (errno));
+ rc = 1;
+ }
+ else
+ {
+ if (parse_and_print (fp))
+ rc = 1;
+ fclose (fp);
+ }
+ }
+ }
+
+ return !!rc;
+}
diff --git a/grub-core/lib/libgcrypt/src/fips.c b/grub-core/lib/libgcrypt/src/fips.c
new file mode 100644
index 0000000..a3445eb
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/fips.c
@@ -0,0 +1,852 @@
+/* fips.c - FIPS mode management
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef ENABLE_HMAC_BINARY_CHECK
+# include <dlfcn.h>
+#endif
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+
+#include "g10lib.h"
+#include "ath.h"
+#include "cipher-proto.h"
+#include "hmac256.h"
+
+
+/* The name of the file used to foce libgcrypt into fips mode. */
+#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
+
+
+/* The states of the finite state machine used in fips mode. */
+enum module_states
+ {
+ /* POWEROFF cannot be represented. */
+ STATE_POWERON = 0,
+ STATE_INIT,
+ STATE_SELFTEST,
+ STATE_OPERATIONAL,
+ STATE_ERROR,
+ STATE_FATALERROR,
+ STATE_SHUTDOWN
+ };
+
+
+/* Flag telling whether we are in fips mode. It uses inverse logic so
+ that fips mode is the default unless changed by the initialization
+ code. To check whether fips mode is enabled, use the function
+ fips_mode()! */
+static int no_fips_mode_required;
+
+/* Flag to indicate that we are in the enforced FIPS mode. */
+static int enforced_fips_mode;
+
+/* If this flag is set, the application may no longer assume that the
+ process is running in FIPS mode. This flag is protected by the
+ FSM_LOCK. */
+static int inactive_fips_mode;
+
+/* This is the lock we use to protect the FSM. */
+static ath_mutex_t fsm_lock;
+
+/* The current state of the FSM. The whole state machinery is only
+ used while in fips mode. Change this only while holding fsm_lock. */
+static enum module_states current_state;
+
+
+
+
+
+static void fips_new_state (enum module_states new_state);
+
+
+
+/* Convert lowercase hex digits; assumes valid hex digits. */
+#define loxtoi_1(p) (*(p) <= '9'? (*(p)- '0'): (*(p)-'a'+10))
+#define loxtoi_2(p) ((loxtoi_1(p) * 16) + loxtoi_1((p)+1))
+
+/* Returns true if P points to a lowercase hex digit. */
+#define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p))
+
+
+
+/* Check whether the OS is in FIPS mode and record that in a module
+ local variable. If FORCE is passed as true, fips mode will be
+ enabled anyway. Note: This function is not thread-safe and should
+ be called before any threads are created. This function may only
+ be called once. */
+void
+_gcry_initialize_fips_mode (int force)
+{
+ static int done;
+ gpg_error_t err;
+
+ /* Make sure we are not accidently called twice. */
+ if (done)
+ {
+ if ( fips_mode () )
+ {
+ fips_new_state (STATE_FATALERROR);
+ fips_noreturn ();
+ }
+ /* If not in fips mode an assert is sufficient. */
+ gcry_assert (!done);
+ }
+ done = 1;
+
+ /* If the calling application explicitly requested fipsmode, do so. */
+ if (force)
+ {
+ gcry_assert (!no_fips_mode_required);
+ goto leave;
+ }
+
+ /* For testing the system it is useful to override the system
+ provided detection of the FIPS mode and force FIPS mode using a
+ file. The filename is hardwired so that there won't be any
+ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
+ actually used. The file itself may be empty. */
+ if ( !access (FIPS_FORCE_FILE, F_OK) )
+ {
+ gcry_assert (!no_fips_mode_required);
+ goto leave;
+ }
+
+ /* Checking based on /proc file properties. */
+ {
+ static const char procfname[] = "/proc/sys/crypto/fips_enabled";
+ FILE *fp;
+ int saved_errno;
+
+ fp = fopen (procfname, "r");
+ if (fp)
+ {
+ char line[256];
+
+ if (fgets (line, sizeof line, fp) && atoi (line))
+ {
+ /* System is in fips mode. */
+ fclose (fp);
+ gcry_assert (!no_fips_mode_required);
+ goto leave;
+ }
+ fclose (fp);
+ }
+ else if ((saved_errno = errno) != ENOENT
+ && saved_errno != EACCES
+ && !access ("/proc/version", F_OK) )
+ {
+ /* Problem reading the fips file despite that we have the proc
+ file system. We better stop right away. */
+ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n",
+ procfname, strerror (saved_errno));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "reading `%s' failed: %s - abort",
+ procfname, strerror (saved_errno));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+ }
+
+ /* Fips not not requested, set flag. */
+ no_fips_mode_required = 1;
+
+ leave:
+ if (!no_fips_mode_required)
+ {
+ /* Yes, we are in FIPS mode. */
+ FILE *fp;
+
+ /* Intitialize the lock to protect the FSM. */
+ err = ath_mutex_init (&fsm_lock);
+ if (err)
+ {
+ /* If that fails we can't do anything but abort the
+ process. We need to use log_info so that the FSM won't
+ get involved. */
+ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
+ strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "creating FSM lock failed: %s - abort",
+ strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+
+
+ /* If the FIPS force files exists, is readable and has a number
+ != 0 on its first line, we enable the enforced fips mode. */
+ fp = fopen (FIPS_FORCE_FILE, "r");
+ if (fp)
+ {
+ char line[256];
+
+ if (fgets (line, sizeof line, fp) && atoi (line))
+ enforced_fips_mode = 1;
+ fclose (fp);
+ }
+
+ /* Now get us into the INIT state. */
+ fips_new_state (STATE_INIT);
+
+ }
+ return;
+}
+
+static void
+lock_fsm (void)
+{
+ gpg_error_t err;
+
+ err = ath_mutex_lock (&fsm_lock);
+ if (err)
+ {
+ log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n",
+ strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "acquiring FSM lock failed: %s - abort",
+ strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+}
+
+static void
+unlock_fsm (void)
+{
+ gpg_error_t err;
+
+ err = ath_mutex_unlock (&fsm_lock);
+ if (err)
+ {
+ log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n",
+ strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "releasing FSM lock failed: %s - abort",
+ strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+}
+
+
+/* This function returns true if fips mode is enabled. This is
+ independent of the fips required finite state machine and only used
+ to enable fips specific code. Please use the fips_mode macro
+ instead of calling this function directly. */
+int
+_gcry_fips_mode (void)
+{
+ /* No locking is required because we have the requirement that this
+ variable is only initialized once with no other threads
+ existing. */
+ return !no_fips_mode_required;
+}
+
+
+/* Return a flag telling whether we are in the enforced fips mode. */
+int
+_gcry_enforced_fips_mode (void)
+{
+ return enforced_fips_mode;
+}
+
+
+/* If we do not want to enforce the fips mode, we can set a flag so
+ that the application may check whether it is still in fips mode.
+ TEXT will be printed as part of a syslog message. This function
+ may only be be called if in fips mode. */
+void
+_gcry_inactivate_fips_mode (const char *text)
+{
+ gcry_assert (_gcry_fips_mode ());
+
+ if (_gcry_enforced_fips_mode () )
+ {
+ /* Get us into the error state. */
+ fips_signal_error (text);
+ return;
+ }
+
+ lock_fsm ();
+ if (!inactive_fips_mode)
+ {
+ inactive_fips_mode = 1;
+ unlock_fsm ();
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+ "%s - FIPS mode inactivated", text);
+#endif /*HAVE_SYSLOG*/
+ }
+ else
+ unlock_fsm ();
+}
+
+
+/* Return the FIPS mode inactive flag. If it is true the FIPS mode is
+ not anymore active. */
+int
+_gcry_is_fips_mode_inactive (void)
+{
+ int flag;
+
+ if (!_gcry_fips_mode ())
+ return 0;
+ lock_fsm ();
+ flag = inactive_fips_mode;
+ unlock_fsm ();
+ return flag;
+}
+
+
+
+static const char *
+state2str (enum module_states state)
+{
+ const char *s;
+
+ switch (state)
+ {
+ case STATE_POWERON: s = "Power-On"; break;
+ case STATE_INIT: s = "Init"; break;
+ case STATE_SELFTEST: s = "Self-Test"; break;
+ case STATE_OPERATIONAL: s = "Operational"; break;
+ case STATE_ERROR: s = "Error"; break;
+ case STATE_FATALERROR: s = "Fatal-Error"; break;
+ case STATE_SHUTDOWN: s = "Shutdown"; break;
+ default: s = "?"; break;
+ }
+ return s;
+}
+
+
+/* Return true if the library is in the operational state. */
+int
+_gcry_fips_is_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ if (current_state == STATE_INIT)
+ {
+ /* If we are still in the INIT state, we need to run the
+ selftests so that the FSM can eventually get into
+ operational state. Given that we would need a 2-phase
+ initialization of libgcrypt, but that has traditionally
+ not been enforced, we use this on demand self-test
+ checking. Note that Proper applications would do the
+ application specific libgcrypt initialization between a
+ gcry_check_version() and gcry_control
+ (GCRYCTL_INITIALIZATION_FINISHED) where the latter will
+ run the selftests. The drawback of these on-demand
+ self-tests are a small chance that self-tests are
+ performed by severeal threads; that is no problem because
+ our FSM make sure that we won't oversee any error. */
+ unlock_fsm ();
+ _gcry_fips_run_selftests (0);
+ lock_fsm ();
+ }
+
+ result = (current_state == STATE_OPERATIONAL);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+/* This is test on whether the library is in the operational state. In
+ contrast to _gcry_fips_is_operational this function won't do a
+ state transition on the fly. */
+int
+_gcry_fips_test_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ result = (current_state == STATE_OPERATIONAL);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+/* This is a test on whether the library is in the error or
+ operational state. */
+int
+_gcry_fips_test_error_or_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ result = (current_state == STATE_OPERATIONAL
+ || current_state == STATE_ERROR);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+static void
+reporter (const char *domain, int algo, const char *what, const char *errtxt)
+{
+ if (!errtxt && !_gcry_log_verbosity (2))
+ return;
+
+ log_info ("libgcrypt selftest: %s %s%s (%d): %s%s%s%s\n",
+ !strcmp (domain, "hmac")? "digest":domain,
+ !strcmp (domain, "hmac")? "HMAC-":"",
+ !strcmp (domain, "cipher")? _gcry_cipher_algo_name (algo) :
+ !strcmp (domain, "digest")? _gcry_md_algo_name (algo) :
+ !strcmp (domain, "hmac")? _gcry_md_algo_name (algo) :
+ !strcmp (domain, "pubkey")? _gcry_pk_algo_name (algo) : "",
+ algo, errtxt? errtxt:"Okay",
+ what?" (":"", what? what:"", what?")":"");
+}
+
+/* Run self-tests for all required cipher algorithms. Return 0 on
+ success. */
+static int
+run_cipher_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_CIPHER_3DES,
+ GCRY_CIPHER_AES128,
+ GCRY_CIPHER_AES192,
+ GCRY_CIPHER_AES256,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_cipher_selftest (algos[idx], extended, reporter);
+ reporter ("cipher", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for all required hash algorithms. Return 0 on
+ success. */
+static int
+run_digest_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_MD_SHA1,
+ GCRY_MD_SHA224,
+ GCRY_MD_SHA256,
+ GCRY_MD_SHA384,
+ GCRY_MD_SHA512,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_md_selftest (algos[idx], extended, reporter);
+ reporter ("digest", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for all HMAC algorithms. Return 0 on success. */
+static int
+run_hmac_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_MD_SHA1,
+ GCRY_MD_SHA224,
+ GCRY_MD_SHA256,
+ GCRY_MD_SHA384,
+ GCRY_MD_SHA512,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_hmac_selftest (algos[idx], extended, reporter);
+ reporter ("hmac", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for all required public key algorithms. Return 0 on
+ success. */
+static int
+run_pubkey_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_PK_RSA,
+ GCRY_PK_DSA,
+ /* GCRY_PK_ECDSA is not enabled in fips mode. */
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_pk_selftest (algos[idx], extended, reporter);
+ reporter ("pubkey", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for the random number generator. Returns 0 on
+ success. */
+static int
+run_random_selftests (void)
+{
+ gpg_error_t err;
+
+ err = _gcry_random_selftest (reporter);
+ reporter ("random", 0, NULL, err? gpg_strerror (err):NULL);
+
+ return !!err;
+}
+
+/* Run an integrity check on the binary. Returns 0 on success. */
+static int
+check_binary_integrity (void)
+{
+#ifdef ENABLE_HMAC_BINARY_CHECK
+ gpg_error_t err;
+ Dl_info info;
+ unsigned char digest[32];
+ int dlen;
+ char *fname = NULL;
+ const char key[] = "What am I, a doctor or a moonshuttle conductor?";
+
+ if (!dladdr ("gcry_check_version", &info))
+ err = gpg_error_from_syserror ();
+ else
+ {
+ dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname,
+ key, strlen (key));
+ if (dlen < 0)
+ err = gpg_error_from_syserror ();
+ else if (dlen != 32)
+ err = gpg_error (GPG_ERR_INTERNAL);
+ else
+ {
+ fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 );
+ if (!fname)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ FILE *fp;
+ char *p;
+
+ /* Prefix the basename with a dot. */
+ strcpy (fname, info.dli_fname);
+ p = strrchr (fname, '/');
+ if (p)
+ p++;
+ else
+ p = fname;
+ memmove (p+1, p, strlen (p)+1);
+ *p = '.';
+ strcat (fname, ".hmac");
+
+ /* Open the file. */
+ fp = fopen (fname, "r");
+ if (!fp)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ /* A buffer of 64 bytes plus one for a LF and one to
+ detect garbage. */
+ unsigned char buffer[64+1+1];
+ const unsigned char *s;
+ int n;
+
+ /* The HMAC files consists of lowercase hex digits
+ only with an optional trailing linefeed. Fail if
+ there is any garbage. */
+ err = gpg_error (GPG_ERR_SELFTEST_FAILED);
+ n = fread (buffer, 1, sizeof buffer, fp);
+ if (n == 64 || (n == 65 && buffer[64] == '\n'))
+ {
+ buffer[64] = 0;
+ for (n=0, s= buffer;
+ n < 32 && loxdigit_p (s) && loxdigit_p (s+1);
+ n++, s += 2)
+ buffer[n] = loxtoi_2 (s);
+ if ( n == 32 && !memcmp (digest, buffer, 32) )
+ err = 0;
+ }
+ fclose (fp);
+ }
+ }
+ }
+ }
+ reporter ("binary", 0, fname, err? gpg_strerror (err):NULL);
+#ifdef HAVE_SYSLOG
+ if (err)
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "integrity check using `%s' failed: %s",
+ fname? fname:"[?]", gpg_strerror (err));
+#endif /*HAVE_SYSLOG*/
+ gcry_free (fname);
+ return !!err;
+#else
+ return 0;
+#endif
+}
+
+
+/* Run the self-tests. If EXTENDED is true, extended versions of the
+ selftest are run, that is more tests than required by FIPS. */
+gpg_err_code_t
+_gcry_fips_run_selftests (int extended)
+{
+ enum module_states result = STATE_ERROR;
+ gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
+
+ if (fips_mode ())
+ fips_new_state (STATE_SELFTEST);
+
+ if (run_cipher_selftests (extended))
+ goto leave;
+
+ if (run_digest_selftests (extended))
+ goto leave;
+
+ if (run_hmac_selftests (extended))
+ goto leave;
+
+ /* Run random tests before the pubkey tests because the latter
+ require random. */
+ if (run_random_selftests ())
+ goto leave;
+
+ if (run_pubkey_selftests (extended))
+ goto leave;
+
+ /* Now check the integrity of the binary. We do this this after
+ having checked the HMAC code. */
+ if (check_binary_integrity ())
+ goto leave;
+
+ /* All selftests passed. */
+ result = STATE_OPERATIONAL;
+ ec = 0;
+
+ leave:
+ if (fips_mode ())
+ fips_new_state (result);
+
+ return ec;
+}
+
+
+/* This function is used to tell the FSM about errors in the library.
+ The FSM will be put into an error state. This function should not
+ be called directly but by one of the macros
+
+ fips_signal_error (description)
+ fips_signal_fatal_error (description)
+
+ where DESCRIPTION is a string describing the error. */
+void
+_gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc,
+ int is_fatal, const char *description)
+{
+ if (!fips_mode ())
+ return; /* Not required. */
+
+ /* Set new state before printing an error. */
+ fips_new_state (is_fatal? STATE_FATALERROR : STATE_ERROR);
+
+ /* Print error. */
+ log_info ("%serror in libgcrypt, file %s, line %d%s%s: %s\n",
+ is_fatal? "fatal ":"",
+ srcfile, srcline,
+ srcfunc? ", function ":"", srcfunc? srcfunc:"",
+ description? description : "no description available");
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "%serror in file %s, line %d%s%s: %s",
+ is_fatal? "fatal ":"",
+ srcfile, srcline,
+ srcfunc? ", function ":"", srcfunc? srcfunc:"",
+ description? description : "no description available");
+#endif /*HAVE_SYSLOG*/
+}
+
+
+/* Perform a state transition to NEW_STATE. If this is an invalid
+ transition, the module will go into a fatal error state. */
+static void
+fips_new_state (enum module_states new_state)
+{
+ int ok = 0;
+ enum module_states last_state;
+
+ lock_fsm ();
+
+ last_state = current_state;
+ switch (current_state)
+ {
+ case STATE_POWERON:
+ if (new_state == STATE_INIT
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_INIT:
+ if (new_state == STATE_SELFTEST
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_SELFTEST:
+ if (new_state == STATE_OPERATIONAL
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_OPERATIONAL:
+ if (new_state == STATE_SHUTDOWN
+ || new_state == STATE_SELFTEST
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_ERROR:
+ if (new_state == STATE_SHUTDOWN
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR
+ || new_state == STATE_SELFTEST)
+ ok = 1;
+ break;
+
+ case STATE_FATALERROR:
+ if (new_state == STATE_SHUTDOWN )
+ ok = 1;
+ break;
+
+ case STATE_SHUTDOWN:
+ /* We won't see any transition *from* Shutdown because the only
+ allowed new state is Power-Off and that one can't be
+ represented. */
+ break;
+
+ }
+
+ if (ok)
+ {
+ current_state = new_state;
+ }
+
+ unlock_fsm ();
+
+ if (!ok || _gcry_log_verbosity (2))
+ log_info ("libgcrypt state transition %s => %s %s\n",
+ state2str (last_state), state2str (new_state),
+ ok? "granted":"denied");
+
+ if (!ok)
+ {
+ /* Invalid state transition. Halting library. */
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR,
+ "Libgcrypt error: invalid state transition %s => %s",
+ state2str (last_state), state2str (new_state));
+#endif /*HAVE_SYSLOG*/
+ fips_noreturn ();
+ }
+ else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR)
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt notice: state transition %s => %s",
+ state2str (last_state), state2str (new_state));
+#endif /*HAVE_SYSLOG*/
+ }
+}
+
+
+
+
+/* This function should be called to ensure that the execution shall
+ not continue. */
+void
+_gcry_fips_noreturn (void)
+{
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application");
+#endif /*HAVE_SYSLOG*/
+ fflush (NULL);
+ abort ();
+ /*NOTREACHED*/
+}
diff --git a/grub-core/lib/libgcrypt/src/g10lib.h b/grub-core/lib/libgcrypt/src/g10lib.h
new file mode 100644
index 0000000..9ef45ec
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/g10lib.h
@@ -0,0 +1,349 @@
+/* g10lib.h - Internal definitions for libgcrypt
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+ * 2007, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This header is to be used inside of libgcrypt in place of gcrypt.h.
+ This way we can better distinguish between internal and external
+ usage of gcrypt.h. */
+
+#ifndef G10LIB_H
+#define G10LIB_H 1
+
+#ifdef _GCRYPT_H
+#error gcrypt.h already included
+#endif
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+#error something is wrong with config.h
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "visibility.h"
+#include "types.h"
+
+
+
+
+/* Attribute handling macros. */
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
+#define JNLIB_GCC_M_FUNCTION 1
+#define JNLIB_GCC_A_NR __attribute__ ((noreturn))
+#define JNLIB_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a)))
+#define JNLIB_GCC_A_NR_PRINTF( f, a ) \
+ __attribute__ ((noreturn, format (printf,f,a)))
+#define GCC_ATTR_NORETURN __attribute__ ((__noreturn__))
+#else
+#define JNLIB_GCC_A_NR
+#define JNLIB_GCC_A_PRINTF( f, a )
+#define JNLIB_GCC_A_NR_PRINTF( f, a )
+#define GCC_ATTR_NORETURN
+#endif
+
+#if __GNUC__ >= 3
+/* According to glibc this attribute is available since 2.8 however we
+ better play safe and use it only with gcc 3 or newer. */
+#define GCC_ATTR_FORMAT_ARG(a) __attribute__ ((format_arg (a)))
+#else
+#define GCC_ATTR_FORMAT_ARG(a)
+#endif
+
+
+/* Gettext macros. */
+
+#define _(a) _gcry_gettext(a)
+
+/* Some handy macros */
+#ifndef STR
+#define STR(v) #v
+#endif
+#define STR2(v) STR(v)
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member) DIM(((type *)0)->member)
+
+
+
+/*-- src/global.c -*/
+int _gcry_global_is_operational (void);
+gcry_error_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr);
+void _gcry_check_heap (const void *a);
+int _gcry_get_debug_flag (unsigned int mask);
+
+
+/*-- src/misc.c --*/
+
+#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
+void _gcry_bug (const char *file, int line,
+ const char *func) GCC_ATTR_NORETURN;
+void _gcry_assert_failed (const char *expr, const char *file, int line,
+ const char *func) GCC_ATTR_NORETURN;
+#else
+void _gcry_bug (const char *file, int line);
+void _gcry_assert_failed (const char *expr, const char *file, int line);
+#endif
+
+const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1);
+void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR;
+void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3);
+void _gcry_log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
+void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
+void _gcry_log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+int _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
+ JNLIB_GCC_A_PRINTF(2,3);
+void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_printhex (const char *text, const void *buffer, size_t length);
+
+void _gcry_set_log_verbosity( int level );
+int _gcry_log_verbosity( int level );
+
+#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__))
+
+#define log_bug _gcry_log_bug
+#define log_fatal _gcry_log_fatal
+#define log_error _gcry_log_error
+#define log_info _gcry_log_info
+#define log_debug _gcry_log_debug
+#define log_printf _gcry_log_printf
+#define log_printhex _gcry_log_printhex
+
+
+/*-- src/hwfeatures.c --*/
+/* (Do not change these values unless synced with the asm code.) */
+#define HWF_PADLOCK_RNG 1
+#define HWF_PADLOCK_AES 2
+#define HWF_PADLOCK_SHA 4
+#define HWF_PADLOCK_MMUL 8
+
+#define HWF_INTEL_AESNI 256
+
+
+unsigned int _gcry_get_hw_features (void);
+void _gcry_detect_hw_features (unsigned int);
+
+
+/*-- mpi/mpiutil.c --*/
+const char *_gcry_mpi_get_hw_config (void);
+
+
+/*-- cipher/pubkey.c --*/
+
+/* FIXME: shouldn't this go into mpi.h? */
+#ifndef mpi_powm
+#define mpi_powm(w,b,e,m) gcry_mpi_powm( (w), (b), (e), (m) )
+#endif
+
+/*-- primegen.c --*/
+gcry_err_code_t _gcry_primegen_init (void);
+gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg);
+gcry_mpi_t _gcry_generate_public_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg);
+gcry_mpi_t _gcry_generate_elg_prime (int mode,
+ unsigned int pbits, unsigned int qbits,
+ gcry_mpi_t g, gcry_mpi_t **factors);
+gcry_mpi_t _gcry_derive_x931_prime (const gcry_mpi_t xp,
+ const gcry_mpi_t xp1, const gcry_mpi_t xp2,
+ const gcry_mpi_t e,
+ gcry_mpi_t *r_p1, gcry_mpi_t *r_p2);
+gpg_err_code_t _gcry_generate_fips186_2_prime
+ (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen);
+gpg_err_code_t _gcry_generate_fips186_3_prime
+ (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen, int *r_hashalgo);
+
+
+/* Replacements of missing functions (missing-string.c). */
+#ifndef HAVE_STPCPY
+char *stpcpy (char *a, const char *b);
+#endif
+#ifndef HAVE_STRCASECMP
+int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE;
+#endif
+
+
+/* Macros used to rename missing functions. */
+#ifndef HAVE_STRTOUL
+#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c)))
+#endif
+#ifndef HAVE_MEMMOVE
+#define memmove(d, s, n) bcopy((s), (d), (n))
+#endif
+#ifndef HAVE_STRICMP
+#define stricmp(a,b) strcasecmp( (a), (b) )
+#endif
+#ifndef HAVE_ATEXIT
+#define atexit(a) (on_exit((a),0))
+#endif
+#ifndef HAVE_RAISE
+#define raise(a) kill(getpid(), (a))
+#endif
+
+
+/* Stack burning. */
+
+void _gcry_burn_stack (int bytes);
+
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+ macros may be used instead. */
+#define wipememory2(_ptr,_set,_len) do { \
+ volatile char *_vptr=(volatile char *)(_ptr); \
+ size_t _vlen=(_len); \
+ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+ } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+
+
+/* Digit predicates. */
+
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
+#define alphap(a) ( (*(a) >= 'A' && *(a) <= 'Z') \
+ || (*(a) >= 'a' && *(a) <= 'z'))
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+
+/* Management for ciphers/digests/pubkey-ciphers. */
+
+/* Structure for each registered `module'. */
+struct gcry_module
+{
+ struct gcry_module *next; /* List pointers. */
+ struct gcry_module **prevp;
+ void *spec; /* Pointer to the subsystem-specific
+ specification structure. */
+ void *extraspec; /* Pointer to the subsystem-specific
+ extra specification structure. */
+ int flags; /* Associated flags. */
+ int counter; /* Use counter. */
+ unsigned int mod_id; /* ID of this module. */
+};
+
+typedef struct gcry_module gcry_module_t;
+
+/* Flags for the `flags' member of gcry_module_t. */
+#define FLAG_MODULE_DISABLED (1 << 0)
+
+gcry_err_code_t _gcry_module_add (gcry_module_t *entries,
+ unsigned int id,
+ void *spec,
+ void *extraspec,
+ gcry_module_t *module);
+
+typedef int (*gcry_module_lookup_t) (void *spec, void *data);
+
+/* Lookup a module specification by it's ID. After a successful
+ lookup, the module has it's resource counter incremented. */
+gcry_module_t _gcry_module_lookup_id (gcry_module_t entries,
+ unsigned int id);
+
+/* Internal function. Lookup a module specification. */
+gcry_module_t _gcry_module_lookup (gcry_module_t entries, void *data,
+ gcry_module_lookup_t func);
+
+/* Release a module. In case the use-counter reaches zero, destroy
+ the module. */
+void _gcry_module_release (gcry_module_t entry);
+
+/* Add a reference to a module. */
+void _gcry_module_use (gcry_module_t module);
+
+/* Return a list of module IDs. */
+gcry_err_code_t _gcry_module_list (gcry_module_t modules,
+ int *list, int *list_length);
+
+gcry_err_code_t _gcry_cipher_init (void);
+gcry_err_code_t _gcry_md_init (void);
+gcry_err_code_t _gcry_pk_init (void);
+
+gcry_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t *module);
+void _gcry_pk_module_release (gcry_module_t module);
+gcry_err_code_t _gcry_pk_get_elements (int algo, char **enc, char **sig);
+
+/* Memory management. */
+#define GCRY_ALLOC_FLAG_SECURE (1 << 0)
+
+
+/*-- sexp.c --*/
+gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, va_list arg_ptr);
+char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number);
+
+
+/*-- fips.c --*/
+
+void _gcry_initialize_fips_mode (int force);
+
+int _gcry_enforced_fips_mode (void);
+
+void _gcry_inactivate_fips_mode (const char *text);
+int _gcry_is_fips_mode_inactive (void);
+
+
+void _gcry_fips_signal_error (const char *srcfile,
+ int srcline,
+ const char *srcfunc,
+ int is_fatal,
+ const char *description);
+#ifdef JNLIB_GCC_M_FUNCTION
+# define fips_signal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 0, (a))
+# define fips_signal_fatal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 1, (a))
+#else
+# define fips_signal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 0, (a))
+# define fips_signal_fatal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a))
+#endif
+
+int _gcry_fips_is_operational (void);
+#define fips_is_operational() (_gcry_global_is_operational ())
+#define fips_not_operational() (GCRY_GPG_ERR_NOT_OPERATIONAL)
+
+int _gcry_fips_test_operational (void);
+int _gcry_fips_test_error_or_operational (void);
+
+gpg_err_code_t _gcry_fips_run_selftests (int extended);
+
+void _gcry_fips_noreturn (void);
+#define fips_noreturn() (_gcry_fips_noreturn ())
+
+
+
+#endif /* G10LIB_H */
diff --git a/grub-core/lib/libgcrypt/src/gcrypt-module.h b/grub-core/lib/libgcrypt/src/gcrypt-module.h
new file mode 100644
index 0000000..93f6162
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/gcrypt-module.h
@@ -0,0 +1,204 @@
+/* gcrypt-module.h - GNU Cryptographic Library Interface
+ Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This file contains the necessary declarations/definitions for
+ working with Libgcrypt modules. Since 1.6 this is an internal
+ interface and will eventually be merged into another header or
+ entirely removed.
+ */
+
+#ifndef GCRYPT_MODULE_H
+#define GCRYPT_MODULE_H
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* keep Emacsens's auto-indent happy */
+}
+#endif
+#endif
+
+/* The interfaces using the module system reserve a certain range of
+ IDs for application use. These IDs are not valid within Libgcrypt
+ but Libgcrypt makes sure never to allocate such a module ID. */
+#define GCRY_MODULE_ID_USER 1024
+#define GCRY_MODULE_ID_USER_LAST 4095
+
+
+/* This type represents a `module'. */
+typedef struct gcry_module *gcry_module_t;
+
+/* Check that the library fulfills the version requirement. */
+
+/* Type for the cipher_setkey function. */
+typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
+ const unsigned char *key,
+ unsigned keylen);
+
+/* Type for the cipher_encrypt function. */
+typedef void (*gcry_cipher_encrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf);
+
+/* Type for the cipher_decrypt function. */
+typedef void (*gcry_cipher_decrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf);
+
+/* Type for the cipher_stencrypt function. */
+typedef void (*gcry_cipher_stencrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf,
+ unsigned int n);
+
+/* Type for the cipher_stdecrypt function. */
+typedef void (*gcry_cipher_stdecrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf,
+ unsigned int n);
+
+typedef struct gcry_cipher_oid_spec
+{
+ const char *oid;
+ int mode;
+} gcry_cipher_oid_spec_t;
+
+/* Module specification structure for ciphers. */
+typedef struct gcry_cipher_spec
+{
+ const char *name;
+ const char **aliases;
+ gcry_cipher_oid_spec_t *oids;
+ size_t blocksize;
+ size_t keylen;
+ size_t contextsize;
+ gcry_cipher_setkey_t setkey;
+ gcry_cipher_encrypt_t encrypt;
+ gcry_cipher_decrypt_t decrypt;
+ gcry_cipher_stencrypt_t stencrypt;
+ gcry_cipher_stdecrypt_t stdecrypt;
+} gcry_cipher_spec_t;
+
+
+/* ********************** */
+
+/* Type for the pk_generate function. */
+typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
+ unsigned int nbits,
+ unsigned long use_e,
+ gcry_mpi_t *skey,
+ gcry_mpi_t **retfactors);
+
+/* Type for the pk_check_secret_key function. */
+typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
+ gcry_mpi_t *skey);
+
+/* Type for the pk_encrypt function. */
+typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo,
+ gcry_mpi_t *resarr,
+ gcry_mpi_t data,
+ gcry_mpi_t *pkey,
+ int flags);
+
+/* Type for the pk_decrypt function. */
+typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo,
+ gcry_mpi_t *result,
+ gcry_mpi_t *data,
+ gcry_mpi_t *skey,
+ int flags);
+
+/* Type for the pk_sign function. */
+typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo,
+ gcry_mpi_t *resarr,
+ gcry_mpi_t data,
+ gcry_mpi_t *skey);
+
+/* Type for the pk_verify function. */
+typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo,
+ gcry_mpi_t hash,
+ gcry_mpi_t *data,
+ gcry_mpi_t *pkey,
+ int (*cmp) (void *, gcry_mpi_t),
+ void *opaquev);
+
+/* Type for the pk_get_nbits function. */
+typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);
+
+/* Module specification structure for message digests. */
+typedef struct gcry_pk_spec
+{
+ const char *name;
+ const char **aliases;
+ const char *elements_pkey;
+ const char *elements_skey;
+ const char *elements_enc;
+ const char *elements_sig;
+ const char *elements_grip;
+ int use;
+ gcry_pk_generate_t generate;
+ gcry_pk_check_secret_key_t check_secret_key;
+ gcry_pk_encrypt_t encrypt;
+ gcry_pk_decrypt_t decrypt;
+ gcry_pk_sign_t sign;
+ gcry_pk_verify_t verify;
+ gcry_pk_get_nbits_t get_nbits;
+} gcry_pk_spec_t;
+
+
+/* ********************** */
+
+/* Type for the md_init function. */
+typedef void (*gcry_md_init_t) (void *c);
+
+/* Type for the md_write function. */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
+
+/* Type for the md_final function. */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function. */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+typedef struct gcry_md_oid_spec
+{
+ const char *oidstring;
+} gcry_md_oid_spec_t;
+
+/* Module specification structure for message digests. */
+typedef struct gcry_md_spec
+{
+ const char *name;
+ unsigned char *asnoid;
+ int asnlen;
+ gcry_md_oid_spec_t *oids;
+ int mdlen;
+ gcry_md_init_t init;
+ gcry_md_write_t write;
+ gcry_md_final_t final;
+ gcry_md_read_t read;
+ size_t contextsize; /* allocate this amount of context */
+} gcry_md_spec_t;
+
+#if 0 /* keep Emacsens's auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /*GCRYPT_MODULE_H*/
diff --git a/grub-core/lib/libgcrypt/src/gcrypt.h.in b/grub-core/lib/libgcrypt/src/gcrypt.h.in
new file mode 100644
index 0000000..8e23ec4
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/gcrypt.h.in
@@ -0,0 +1,1337 @@
+/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*-
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ File: @configure_input@ */
+
+#ifndef _GCRYPT_H
+#define _GCRYPT_H
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <gpg-error.h>
+
+#include <sys/types.h>
+
+#if defined _WIN32 || defined __WIN32__
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <time.h>
+# ifndef __GNUC__
+ typedef long ssize_t;
+ typedef int pid_t;
+# endif /*!__GNUC__*/
+#else
+# include <sys/socket.h>
+# include <sys/time.h>
+#@INSERT_SYS_SELECT_H@
+#endif /*!_WIN32*/
+
+@FALLBACK_SOCKLEN_T@
+
+/* This is required for error code compatibility. */
+#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+}
+#endif
+#endif
+
+/* The version of this header should match the one of the library. It
+ should not be used by a program because gcry_check_version() should
+ return the same version. The purpose of this macro is to let
+ autoconf (using the AM_PATH_GCRYPT macro) check that this header
+ matches the installed library. */
+#define GCRYPT_VERSION "@VERSION@"
+
+/* Internal: We can't use the convenience macros for the multi
+ precision integer functions when building this library. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#ifndef GCRYPT_NO_MPI_MACROS
+#define GCRYPT_NO_MPI_MACROS 1
+#endif
+#endif
+
+/* We want to use gcc attributes when possible. Warning: Don't use
+ these macros in your programs: As indicated by the leading
+ underscore they are subject to change without notice. */
+#ifdef __GNUC__
+
+#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+
+#if _GCRY_GCC_VERSION >= 30100
+#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 29600
+#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 30200
+#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__))
+#endif
+
+#endif /*__GNUC__*/
+
+#ifndef _GCRY_GCC_ATTR_DEPRECATED
+#define _GCRY_GCC_ATTR_DEPRECATED
+#endif
+#ifndef _GCRY_GCC_ATTR_PURE
+#define _GCRY_GCC_ATTR_PURE
+#endif
+#ifndef _GCRY_GCC_ATTR_MALLOC
+#define _GCRY_GCC_ATTR_MALLOC
+#endif
+
+/* Make up an attribute to mark functions and types as deprecated but
+ allow internal use by Libgcrypt. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#define _GCRY_ATTR_INTERNAL
+#else
+#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED
+#endif
+
+/* Wrappers for the libgpg-error library. */
+
+typedef gpg_error_t gcry_error_t;
+typedef gpg_err_code_t gcry_err_code_t;
+typedef gpg_err_source_t gcry_err_source_t;
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_err_make (gcry_err_source_t source, gcry_err_code_t code)
+{
+ return gpg_err_make (source, code);
+}
+
+/* The user can define GPG_ERR_SOURCE_DEFAULT before including this
+ file to specify a default source for gpg_error. */
+#ifndef GCRY_ERR_SOURCE_DEFAULT
+#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1
+#endif
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_error (gcry_err_code_t code)
+{
+ return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code);
+}
+
+static GPG_ERR_INLINE gcry_err_code_t
+gcry_err_code (gcry_error_t err)
+{
+ return gpg_err_code (err);
+}
+
+
+static GPG_ERR_INLINE gcry_err_source_t
+gcry_err_source (gcry_error_t err)
+{
+ return gpg_err_source (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+ code in the error value ERR. */
+const char *gcry_strerror (gcry_error_t err);
+
+/* Return a pointer to a string containing a description of the error
+ source in the error value ERR. */
+const char *gcry_strsource (gcry_error_t err);
+
+/* Retrieve the error code for the system error ERR. This returns
+ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+ this). */
+gcry_err_code_t gcry_err_code_from_errno (int err);
+
+/* Retrieve the system error for the error code CODE. This returns 0
+ if CODE is not a system error code. */
+int gcry_err_code_to_errno (gcry_err_code_t code);
+
+/* Return an error value with the error source SOURCE and the system
+ error ERR. */
+gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
+
+/* Return an error value with the system error ERR. */
+gcry_err_code_t gcry_error_from_errno (int err);
+
+
+/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore
+ used. However we keep it to allow for some source code
+ compatibility if used in the standard way. */
+
+/* Constants defining the thread model to use. Used with the OPTION
+ field of the struct gcry_thread_cbs. */
+#define GCRY_THREAD_OPTION_DEFAULT 0
+#define GCRY_THREAD_OPTION_USER 1
+#define GCRY_THREAD_OPTION_PTH 2
+#define GCRY_THREAD_OPTION_PTHREAD 3
+
+/* The version number encoded in the OPTION field of the struct
+ gcry_thread_cbs. */
+#define GCRY_THREAD_OPTION_VERSION 1
+
+/* Wrapper for struct ath_ops. */
+struct gcry_thread_cbs
+{
+ /* The OPTION field encodes the thread model and the version number
+ of this structure.
+ Bits 7 - 0 are used for the thread model
+ Bits 15 - 8 are used for the version number. */
+ unsigned int option;
+} _GCRY_ATTR_INTERNAL;
+
+#define GCRY_THREAD_OPTION_PTH_IMPL \
+ static struct gcry_thread_cbs gcry_threads_pth = { \
+ (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))}
+
+#define GCRY_THREAD_OPTION_PTHREAD_IMPL \
+ static struct gcry_thread_cbs gcry_threads_pthread = { \
+ (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))}
+
+
+
+/* The data object used to hold a multi precision integer. */
+struct gcry_mpi;
+typedef struct gcry_mpi *gcry_mpi_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+
+
+/* Check that the library fulfills the version requirement. */
+const char *gcry_check_version (const char *req_version);
+
+/* Codes for function dispatchers. */
+
+/* Codes used with the gcry_control function. */
+enum gcry_ctl_cmds
+ {
+ GCRYCTL_SET_KEY = 1,
+ GCRYCTL_SET_IV = 2,
+ GCRYCTL_CFB_SYNC = 3,
+ GCRYCTL_RESET = 4, /* e.g. for MDs */
+ GCRYCTL_FINALIZE = 5,
+ GCRYCTL_GET_KEYLEN = 6,
+ GCRYCTL_GET_BLKLEN = 7,
+ GCRYCTL_TEST_ALGO = 8,
+ GCRYCTL_IS_SECURE = 9,
+ GCRYCTL_GET_ASNOID = 10,
+ GCRYCTL_ENABLE_ALGO = 11,
+ GCRYCTL_DISABLE_ALGO = 12,
+ GCRYCTL_DUMP_RANDOM_STATS = 13,
+ GCRYCTL_DUMP_SECMEM_STATS = 14,
+ GCRYCTL_GET_ALGO_NPKEY = 15,
+ GCRYCTL_GET_ALGO_NSKEY = 16,
+ GCRYCTL_GET_ALGO_NSIGN = 17,
+ GCRYCTL_GET_ALGO_NENCR = 18,
+ GCRYCTL_SET_VERBOSITY = 19,
+ GCRYCTL_SET_DEBUG_FLAGS = 20,
+ GCRYCTL_CLEAR_DEBUG_FLAGS = 21,
+ GCRYCTL_USE_SECURE_RNDPOOL= 22,
+ GCRYCTL_DUMP_MEMORY_STATS = 23,
+ GCRYCTL_INIT_SECMEM = 24,
+ GCRYCTL_TERM_SECMEM = 25,
+ GCRYCTL_DISABLE_SECMEM_WARN = 27,
+ GCRYCTL_SUSPEND_SECMEM_WARN = 28,
+ GCRYCTL_RESUME_SECMEM_WARN = 29,
+ GCRYCTL_DROP_PRIVS = 30,
+ GCRYCTL_ENABLE_M_GUARD = 31,
+ GCRYCTL_START_DUMP = 32,
+ GCRYCTL_STOP_DUMP = 33,
+ GCRYCTL_GET_ALGO_USAGE = 34,
+ GCRYCTL_IS_ALGO_ENABLED = 35,
+ GCRYCTL_DISABLE_INTERNAL_LOCKING = 36,
+ GCRYCTL_DISABLE_SECMEM = 37,
+ GCRYCTL_INITIALIZATION_FINISHED = 38,
+ GCRYCTL_INITIALIZATION_FINISHED_P = 39,
+ GCRYCTL_ANY_INITIALIZATION_P = 40,
+ GCRYCTL_SET_CBC_CTS = 41,
+ GCRYCTL_SET_CBC_MAC = 42,
+ GCRYCTL_SET_CTR = 43,
+ GCRYCTL_ENABLE_QUICK_RANDOM = 44,
+ GCRYCTL_SET_RANDOM_SEED_FILE = 45,
+ GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46,
+ GCRYCTL_SET_THREAD_CBS = 47,
+ GCRYCTL_FAST_POLL = 48,
+ GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49,
+ GCRYCTL_USE_RANDOM_DAEMON = 50,
+ GCRYCTL_FAKED_RANDOM_P = 51,
+ GCRYCTL_SET_RNDEGD_SOCKET = 52,
+ GCRYCTL_PRINT_CONFIG = 53,
+ GCRYCTL_OPERATIONAL_P = 54,
+ GCRYCTL_FIPS_MODE_P = 55,
+ GCRYCTL_FORCE_FIPS_MODE = 56,
+ GCRYCTL_SELFTEST = 57,
+ /* Note: 58 .. 62 are used internally. */
+ GCRYCTL_DISABLE_HWF = 63
+ };
+
+/* Perform various operations defined by CMD. */
+gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...);
+
+
+/* S-expression management. */
+
+/* The object to represent an S-expression as used with the public key
+ functions. */
+struct gcry_sexp;
+typedef struct gcry_sexp *gcry_sexp_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* The possible values for the S-expression format. */
+enum gcry_sexp_format
+ {
+ GCRYSEXP_FMT_DEFAULT = 0,
+ GCRYSEXP_FMT_CANON = 1,
+ GCRYSEXP_FMT_BASE64 = 2,
+ GCRYSEXP_FMT_ADVANCED = 3
+ };
+
+/* Create an new S-expression object from BUFFER of size LENGTH and
+ return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER
+ is expected to be in canonized format. */
+gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp,
+ const void *buffer, size_t length,
+ int autodetect);
+
+ /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the
+ effect to transfer ownership of BUFFER to the created object. */
+gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp,
+ void *buffer, size_t length,
+ int autodetect, void (*freefnc) (void *));
+
+/* Scan BUFFER and return a new S-expression object in RETSEXP. This
+ function expects a printf like string in BUFFER. */
+gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length);
+
+/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus
+ only be used for certain encodings. */
+gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, ...);
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+ function arguments. */
+gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list);
+
+/* Release the S-expression object SEXP */
+void gcry_sexp_release (gcry_sexp_t sexp);
+
+/* Calculate the length of an canonized S-expresion in BUFFER and
+ check for a valid encoding. */
+size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode);
+
+/* Copies the S-expression object SEXP into BUFFER using the format
+ specified in MODE. */
+size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
+ size_t maxlength);
+
+/* Dumps the S-expression object A in a format suitable for debugging
+ to Libgcrypt's logging stream. */
+void gcry_sexp_dump (const gcry_sexp_t a);
+
+gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b);
+gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array);
+gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...);
+gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n);
+gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n);
+
+/* Scan the S-expression for a sublist with a type (the car of the
+ list) matching the string TOKEN. If TOKLEN is not 0, the token is
+ assumed to be raw memory of this length. The function returns a
+ newly allocated S-expression consisting of the found sublist or
+ `NULL' when not found. */
+gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list,
+ const char *tok, size_t toklen);
+/* Return the length of the LIST. For a valid S-expression this
+ should be at least 1. */
+int gcry_sexp_length (const gcry_sexp_t list);
+
+/* Create and return a new S-expression from the element with index
+ NUMBER in LIST. Note that the first element has the index 0. If
+ there is no such element, `NULL' is returned. */
+gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number);
+
+/* Create and return a new S-expression from the first element in
+ LIST; this called the "type" and should always exist and be a
+ string. `NULL' is returned in case of a problem. */
+gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list);
+
+/* Create and return a new list form all elements except for the first
+ one. Note, that this function may return an invalid S-expression
+ because it is not guaranteed, that the type exists and is a string.
+ However, for parsing a complex S-expression it might be useful for
+ intermediate lists. Returns `NULL' on error. */
+gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list);
+
+gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);
+
+
+/* This function is used to get data from a LIST. A pointer to the
+ actual data with index NUMBER is returned and the length of this
+ data will be stored to DATALEN. If there is no data at the given
+ index or the index represents another list, `NULL' is returned.
+ *Note:* The returned pointer is valid as long as LIST is not
+ modified or released. */
+const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number,
+ size_t *datalen);
+
+/* This function is used to get and convert data from a LIST. The
+ data is assumed to be a Nul terminated string. The caller must
+ release the returned value using `gcry_free'. If there is no data
+ at the given index, the index represents a list or the value can't
+ be converted to a string, `NULL' is returned. */
+char *gcry_sexp_nth_string (gcry_sexp_t list, int number);
+
+/* This function is used to get and convert data from a LIST. This
+ data is assumed to be an MPI stored in the format described by
+ MPIFMT and returned as a standard Libgcrypt MPI. The caller must
+ release this returned value using `gcry_mpi_release'. If there is
+ no data at the given index, the index represents a list or the
+ value can't be converted to an MPI, `NULL' is returned. */
+gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
+
+
+
+/*******************************************
+ * *
+ * Multi Precision Integer Functions *
+ * *
+ *******************************************/
+
+/* Different formats of external big integer representation. */
+enum gcry_mpi_format
+ {
+ GCRYMPI_FMT_NONE= 0,
+ GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */
+ GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */
+ GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */
+ GCRYMPI_FMT_HEX = 4, /* Hex format. */
+ GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */
+ };
+
+/* Flags used for creating big integers. */
+enum gcry_mpi_flag
+ {
+ GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */
+ GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just
+ a way to store some bytes. This is
+ useful for encrypted big integers. */
+ };
+
+
+/* Allocate a new big integer object, initialize it with 0 and
+ initially allocate memory for a number of at least NBITS. */
+gcry_mpi_t gcry_mpi_new (unsigned int nbits);
+
+/* Same as gcry_mpi_new() but allocate in "secure" memory. */
+gcry_mpi_t gcry_mpi_snew (unsigned int nbits);
+
+/* Release the number A and free all associated resources. */
+void gcry_mpi_release (gcry_mpi_t a);
+
+/* Create a new number with the same value as A. */
+gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a);
+
+/* Store the big integer value U in W. */
+gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);
+
+/* Store the unsigned integer value U in W. */
+gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);
+
+/* Swap the values of A and B. */
+void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);
+
+/* Compare the big integer number U and V returning 0 for equality, a
+ positive value for U > V and a negative for U < V. */
+int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
+
+/* Compare the big integer number U with the unsigned integer V
+ returning 0 for equality, a positive value for U > V and a negative
+ for U < V. */
+int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
+
+/* Convert the external representation of an integer stored in BUFFER
+ with a length of BUFLEN into a newly create MPI returned in
+ RET_MPI. If NSCANNED is not NULL, it will receive the number of
+ bytes actually scanned after a successful operation. */
+gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+ const void *buffer, size_t buflen,
+ size_t *nscanned);
+
+/* Convert the big integer A into the external representation
+ described by FORMAT and store it in the provided BUFFER which has
+ been allocated by the user with a size of BUFLEN bytes. NWRITTEN
+ receives the actual length of the external representation unless it
+ has been passed as NULL. */
+gcry_error_t gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten,
+ const gcry_mpi_t a);
+
+/* Convert the big integer A int the external representation described
+ by FORMAT and store it in a newly allocated buffer which address
+ will be put into BUFFER. NWRITTEN receives the actual lengths of the
+ external representation. */
+gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ const gcry_mpi_t a);
+
+/* Dump the value of A in a format suitable for debugging to
+ Libgcrypt's logging stream. Note that one leading space but no
+ trailing space or linefeed will be printed. It is okay to pass
+ NULL for A. */
+void gcry_mpi_dump (const gcry_mpi_t a);
+
+
+/* W = U + V. */
+void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U + V. V is an unsigned integer. */
+void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);
+
+/* W = U + V mod M. */
+void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U - V. */
+void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U - V. V is an unsigned integer. */
+void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U - V mod M */
+void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * V. */
+void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U * V. V is an unsigned integer. */
+void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U * V mod M. */
+void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * (2 ^ CNT). */
+void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);
+
+/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR,
+ Q or R may be passed as NULL. ROUND should be negative or 0. */
+void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+ gcry_mpi_t dividend, gcry_mpi_t divisor, int round);
+
+/* R = DIVIDEND % DIVISOR */
+void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+
+/* W = B ^ E mod M. */
+void gcry_mpi_powm (gcry_mpi_t w,
+ const gcry_mpi_t b, const gcry_mpi_t e,
+ const gcry_mpi_t m);
+
+/* Set G to the greatest common divisor of A and B.
+ Return true if the G is 1. */
+int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
+
+/* Set X to the multiplicative inverse of A mod M.
+ Return true if the value exists. */
+int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);
+
+
+/* Return the number of bits required to represent A. */
+unsigned int gcry_mpi_get_nbits (gcry_mpi_t a);
+
+/* Return true when bit number N (counting from 0) is set in A. */
+int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A. */
+void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A. */
+void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A and clear all bits greater than N. */
+void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A and all bits greater than N. */
+void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the right and store the result in X. */
+void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the left and store the result in X. */
+void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Store NBITS of the value P points to in A and mark A as an opaque
+ value. WARNING: Never use an opaque MPI for anything thing else then
+ gcry_mpi_release, gcry_mpi_get_opaque. */
+gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
+
+/* Return a pointer to an opaque value stored in A and return its size
+ in NBITS. Note that the returned pointer is still owned by A and
+ that the function should never be used for an non-opaque MPI. */
+void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);
+
+/* Set the FLAG for the big integer A. Currently only the flag
+ GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger
+ stored in "secure" memory. */
+void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Clear FLAG for the big integer A. Note that this function is
+ currently useless as no flags are allowed. */
+void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Return true when the FLAG is set for A. */
+int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of
+ convenience macros for the big integer functions. */
+#ifndef GCRYPT_NO_MPI_MACROS
+#define mpi_new(n) gcry_mpi_new( (n) )
+#define mpi_secure_new( n ) gcry_mpi_snew( (n) )
+#define mpi_release(a) \
+ do \
+ { \
+ gcry_mpi_release ((a)); \
+ (a) = NULL; \
+ } \
+ while (0)
+
+#define mpi_copy( a ) gcry_mpi_copy( (a) )
+#define mpi_set( w, u) gcry_mpi_set( (w), (u) )
+#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) )
+#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) )
+#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) )
+
+#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
+#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v))
+#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
+#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
+#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v))
+#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
+#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v))
+#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
+#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v))
+#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m))
+#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) )
+#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0)
+#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1)
+#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m))
+#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) )
+#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) )
+
+#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a))
+#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b))
+#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b))
+#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b))
+#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b))
+#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
+#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c))
+#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c))
+
+#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) )
+#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) )
+#endif /* GCRYPT_NO_MPI_MACROS */
+
+
+
+/************************************
+ * *
+ * Symmetric Cipher Functions *
+ * *
+ ************************************/
+
+/* The data object used to hold a handle to an encryption object. */
+struct gcry_cipher_handle;
+typedef struct gcry_cipher_handle *gcry_cipher_hd_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* All symmetric encryption algorithms are identified by their IDs.
+ More IDs may be registered at runtime. */
+enum gcry_cipher_algos
+ {
+ GCRY_CIPHER_NONE = 0,
+ GCRY_CIPHER_IDEA = 1,
+ GCRY_CIPHER_3DES = 2,
+ GCRY_CIPHER_CAST5 = 3,
+ GCRY_CIPHER_BLOWFISH = 4,
+ GCRY_CIPHER_SAFER_SK128 = 5,
+ GCRY_CIPHER_DES_SK = 6,
+ GCRY_CIPHER_AES = 7,
+ GCRY_CIPHER_AES192 = 8,
+ GCRY_CIPHER_AES256 = 9,
+ GCRY_CIPHER_TWOFISH = 10,
+
+ /* Other cipher numbers are above 300 for OpenPGP reasons. */
+ GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */
+ GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */
+ GCRY_CIPHER_TWOFISH128 = 303,
+ GCRY_CIPHER_SERPENT128 = 304,
+ GCRY_CIPHER_SERPENT192 = 305,
+ GCRY_CIPHER_SERPENT256 = 306,
+ GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */
+ GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */
+ GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */
+ GCRY_CIPHER_CAMELLIA128 = 310,
+ GCRY_CIPHER_CAMELLIA192 = 311,
+ GCRY_CIPHER_CAMELLIA256 = 312
+ };
+
+/* The Rijndael algorithm is basically AES, so provide some macros. */
+#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128
+#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192
+#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256
+
+/* The supported encryption modes. Note that not all of them are
+ supported for each algorithm. */
+enum gcry_cipher_modes
+ {
+ GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */
+ GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */
+ GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */
+ GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */
+ GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */
+ GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */
+ GCRY_CIPHER_MODE_CTR = 6, /* Counter. */
+ GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */
+ };
+
+/* Flags used with the open function. */
+enum gcry_cipher_flags
+ {
+ GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */
+ GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */
+ GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */
+ GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */
+ };
+
+
+/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may
+ be given as an bitwise OR of the gcry_cipher_flags values. */
+gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags);
+
+/* Close the cioher handle H and release all resource. */
+void gcry_cipher_close (gcry_cipher_hd_t h);
+
+/* Perform various operations on the cipher object H. */
+gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
+ size_t buflen);
+
+/* Retrieve various information about the cipher object H. */
+gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+
+/* Retrieve various information about the cipher algorithm ALGO. */
+gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
+ string representation of the algorithm name. For unknown algorithm
+ IDs this function returns "?". */
+const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if
+ the algorithm name is not known. */
+int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+
+/* Given an ASN.1 object identifier in standard IETF dotted decimal
+ format in STRING, return the encryption mode associated with that
+ OID or 0 if not known or applicable. */
+int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;
+
+/* Encrypt the plaintext of size INLEN in IN using the cipher handle H
+ into the buffer OUT which has an allocated length of OUTSIZE. For
+ most algorithms it is possible to pass NULL for in and 0 for INLEN
+ and do a in-place decryption of the data provided in OUT. */
+gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+
+/* The counterpart to gcry_cipher_encrypt. */
+gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+
+/* Set KEY of length KEYLEN bytes for the cipher handle HD. */
+gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd,
+ const void *key, size_t keylen);
+
+
+/* Set initialization vector IV of length IVLEN for the cipher handle HD. */
+gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
+ const void *iv, size_t ivlen);
+
+
+/* Reset the handle to the state after open. */
+#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+/* Perform the OpenPGP sync operation if this is enabled for the
+ cipher handle H. */
+#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0)
+
+/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */
+#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \
+ NULL, on )
+
+/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of
+ block size length, or (NULL,0) to set the CTR to the all-zero block. */
+gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
+ const void *ctr, size_t ctrlen);
+
+/* Retrieve the key length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_keylen (int algo);
+
+/* Retrieve the block length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_blklen (int algo);
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_cipher_test_algo(a) \
+ gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+
+/************************************
+ * *
+ * Asymmetric Cipher Functions *
+ * *
+ ************************************/
+
+/* The algorithms and their IDs we support. */
+enum gcry_pk_algos
+ {
+ GCRY_PK_RSA = 1,
+ GCRY_PK_RSA_E = 2, /* (deprecated) */
+ GCRY_PK_RSA_S = 3, /* (deprecated) */
+ GCRY_PK_ELG_E = 16,
+ GCRY_PK_DSA = 17,
+ GCRY_PK_ELG = 20,
+ GCRY_PK_ECDSA = 301,
+ GCRY_PK_ECDH = 302
+ };
+
+/* Flags describing usage capabilities of a PK algorithm. */
+#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */
+#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */
+#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */
+#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */
+#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */
+
+/* Encrypt the DATA using the public key PKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Decrypt the DATA using the private key SKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Sign the DATA using the private key SKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_sign (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Check the signature SIGVAL on DATA using the public key PKEY. */
+gcry_error_t gcry_pk_verify (gcry_sexp_t sigval,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Check that private KEY is sane. */
+gcry_error_t gcry_pk_testkey (gcry_sexp_t key);
+
+/* Generate a new key pair according to the parameters given in
+ S_PARMS. The new key pair is returned in as an S-expression in
+ R_KEY. */
+gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms);
+
+/* Catch all function for miscellaneous operations. */
+gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen);
+
+/* Retrieve information about the public key algorithm ALGO. */
+gcry_error_t gcry_pk_algo_info (int algo, int what,
+ void *buffer, size_t *nbytes);
+
+/* Map the public key algorithm whose ID is contained in ALGORITHM to
+ a string representation of the algorithm name. For unknown
+ algorithm IDs this functions returns "?". */
+const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a public key algorithm Id. Return 0 if
+ the algorithm name is not known. */
+int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* Return what is commonly referred as the key length for the given
+ public or private KEY. */
+unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
+
+/* Please note that keygrip is still experimental and should not be
+ used without contacting the author. */
+unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
+
+/* Return the name of the curve matching KEY. */
+const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator,
+ unsigned int *r_nbits);
+
+/* Return an S-expression with the parameters of the named ECC curve
+ NAME. ALGO must be set to an ECC algorithm. */
+gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
+
+/* Return 0 if the public key algorithm A is available for use. */
+#define gcry_pk_test_algo(a) \
+ gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+
+
+
+/************************************
+ * *
+ * Cryptograhic Hash Functions *
+ * *
+ ************************************/
+
+/* Algorithm IDs for the hash functions we know about. Not all of them
+ are implemnted. */
+enum gcry_md_algos
+ {
+ GCRY_MD_NONE = 0,
+ GCRY_MD_MD5 = 1,
+ GCRY_MD_SHA1 = 2,
+ GCRY_MD_RMD160 = 3,
+ GCRY_MD_MD2 = 5,
+ GCRY_MD_TIGER = 6, /* TIGER/192 as used by gpg <= 1.3.2. */
+ GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */
+ GCRY_MD_SHA256 = 8,
+ GCRY_MD_SHA384 = 9,
+ GCRY_MD_SHA512 = 10,
+ GCRY_MD_SHA224 = 11,
+ GCRY_MD_MD4 = 301,
+ GCRY_MD_CRC32 = 302,
+ GCRY_MD_CRC32_RFC1510 = 303,
+ GCRY_MD_CRC24_RFC2440 = 304,
+ GCRY_MD_WHIRLPOOL = 305,
+ GCRY_MD_TIGER1 = 306, /* TIGER fixed. */
+ GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */
+ };
+
+/* Flags used with the open function. */
+enum gcry_md_flags
+ {
+ GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */
+ GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */
+ };
+
+/* (Forward declaration.) */
+struct gcry_md_context;
+
+/* This object is used to hold a handle to a message digest object.
+ This structure is private - only to be used by the public gcry_md_*
+ macros. */
+typedef struct gcry_md_handle
+{
+ /* Actual context. */
+ struct gcry_md_context *ctx;
+
+ /* Buffer management. */
+ int bufpos;
+ int bufsize;
+ unsigned char buf[1];
+} *gcry_md_hd_t;
+
+/* Compatibility types, do not use them. */
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* Create a message digest object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of the gcry_md_flags values. ALGO may be
+ given as 0 if the algorithms to be used are later set using
+ gcry_md_enable. */
+gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);
+
+/* Release the message digest object HD. */
+void gcry_md_close (gcry_md_hd_t hd);
+
+/* Add the message digest algorithm ALGO to the digest object HD. */
+gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo);
+
+/* Create a new digest object as an exact copy of the object HD. */
+gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);
+
+/* Reset the digest object HD to its initial state. */
+void gcry_md_reset (gcry_md_hd_t hd);
+
+/* Perform various operations on the digest object HD. */
+gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd,
+ void *buffer, size_t buflen);
+
+/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that
+ it can update the digest values. This is the actual hash
+ function. */
+void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
+
+/* Read out the final digest from HD return the digest value for
+ algorithm ALGO. */
+unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
+
+/* Convenience function to calculate the hash from the data in BUFFER
+ of size LENGTH using the algorithm ALGO avoiding the creating of a
+ hash object. The hash is returned in the caller provided buffer
+ DIGEST which must be large enough to hold the digest of the given
+ algorithm. */
+void gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length);
+
+/* Retrieve the algorithm used with HD. This does not work reliable
+ if more than one algorithm is enabled in HD. */
+int gcry_md_get_algo (gcry_md_hd_t hd);
+
+/* Retrieve the length in bytes of the digest yielded by algorithm
+ ALGO. */
+unsigned int gcry_md_get_algo_dlen (int algo);
+
+/* Return true if the the algorithm ALGO is enabled in the digest
+ object A. */
+int gcry_md_is_enabled (gcry_md_hd_t a, int algo);
+
+/* Return true if the digest object A is allocated in "secure" memory. */
+int gcry_md_is_secure (gcry_md_hd_t a);
+
+/* Retrieve various information about the object H. */
+gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+
+/* Retrieve various information about the algorithm ALGO. */
+gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Map the digest algorithm id ALGO to a string representation of the
+ algorithm name. For unknown algorithms this function returns
+ "?". */
+const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a digest algorithm Id. Return 0 if
+ the algorithm name is not known. */
+int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* For use with the HMAC feature, the set MAC key to the KEY of
+ KEYLEN bytes. */
+gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen);
+
+/* Start or stop debugging for digest handle HD; i.e. create a file
+ named dbgmd-<n>.<suffix> while hashing. If SUFFIX is NULL,
+ debugging stops and the file will be closed. */
+void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
+
+
+/* Update the hash(s) of H with the character C. This is a buffered
+ version of the gcry_md_write function. */
+#define gcry_md_putc(h,c) \
+ do { \
+ gcry_md_hd_t h__ = (h); \
+ if( (h__)->bufpos == (h__)->bufsize ) \
+ gcry_md_write( (h__), NULL, 0 ); \
+ (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \
+ } while(0)
+
+/* Finalize the digest calculation. This is not really needed because
+ gcry_md_read() does this implicitly. */
+#define gcry_md_final(a) \
+ gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_md_test_algo(a) \
+ gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N
+ must point to size_t variable with the available size of buffer B.
+ After return it will receive the actual size of the returned
+ OID. */
+#define gcry_md_get_asnoid(a,b,n) \
+ gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
+
+
+
+/******************************
+ * *
+ * Key Derivation Functions *
+ * *
+ ******************************/
+
+/* Algorithm IDs for the KDFs. */
+enum gcry_kdf_algos
+ {
+ GCRY_KDF_NONE = 0,
+ GCRY_KDF_SIMPLE_S2K = 16,
+ GCRY_KDF_SALTED_S2K = 17,
+ GCRY_KDF_ITERSALTED_S2K = 19,
+ GCRY_KDF_PBKDF1 = 33,
+ GCRY_KDF_PBKDF2 = 34
+ };
+
+/* Derive a key from a passphrase. */
+gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int subalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer);
+
+
+
+
+/************************************
+ * *
+ * Random Generating Functions *
+ * *
+ ************************************/
+
+/* The possible values for the random quality. The rule of thumb is
+ to use STRONG for session keys and VERY_STRONG for key material.
+ WEAK is usually an alias for STRONG and should not be used anymore
+ (except with gcry_mpi_randomize); use gcry_create_nonce instead. */
+typedef enum gcry_random_level
+ {
+ GCRY_WEAK_RANDOM = 0,
+ GCRY_STRONG_RANDOM = 1,
+ GCRY_VERY_STRONG_RANDOM = 2
+ }
+gcry_random_level_t;
+
+/* Fill BUFFER with LENGTH bytes of random, using random numbers of
+ quality LEVEL. */
+void gcry_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+
+/* Add the external random from BUFFER with LENGTH bytes into the
+ pool. QUALITY should either be -1 for unknown or in the range of 0
+ to 100 */
+gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length,
+ int quality);
+
+/* If random numbers are used in an application, this macro should be
+ called from time to time so that new stuff gets added to the
+ internal pool of the RNG. */
+#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL)
+
+
+/* Return NBYTES of allocated random using a random numbers of quality
+ LEVEL. */
+void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+
+/* Return NBYTES of allocated random using a random numbers of quality
+ LEVEL. The random numbers are created returned in "secure"
+ memory. */
+void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+
+
+/* Set the big integer W to a random value of NBITS using a random
+ generator with quality LEVEL. Note that by using a level of
+ GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */
+void gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level);
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void gcry_create_nonce (void *buffer, size_t length);
+
+
+
+
+
+/*******************************/
+/* */
+/* Prime Number Functions */
+/* */
+/*******************************/
+
+/* Mode values passed to a gcry_prime_check_func_t. */
+#define GCRY_PRIME_CHECK_AT_FINISH 0
+#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1
+#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2
+
+/* The function should return 1 if the operation shall continue, 0 to
+ reject the prime candidate. */
+typedef int (*gcry_prime_check_func_t) (void *arg, int mode,
+ gcry_mpi_t candidate);
+
+/* Flags for gcry_prime_generate(): */
+
+/* Allocate prime numbers and factors in secure memory. */
+#define GCRY_PRIME_FLAG_SECRET (1 << 0)
+
+/* Make sure that at least one prime factor is of size
+ `FACTOR_BITS'. */
+#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1)
+
+/* Generate a new prime number of PRIME_BITS bits and store it in
+ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of
+ (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is
+ non-zero, allocate a new, NULL-terminated array holding the prime
+ factors and store it in FACTORS. FLAGS might be used to influence
+ the prime number generation process. */
+gcry_error_t gcry_prime_generate (gcry_mpi_t *prime,
+ unsigned int prime_bits,
+ unsigned int factor_bits,
+ gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func,
+ void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags);
+
+/* Find a generator for PRIME where the factorization of (prime-1) is
+ in the NULL terminated array FACTORS. Return the generator as a
+ newly allocated MPI in R_G. If START_G is not NULL, use this as
+ teh start for the search. */
+gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime,
+ gcry_mpi_t *factors,
+ gcry_mpi_t start_g);
+
+
+/* Convenience function to release the FACTORS array. */
+void gcry_prime_release_factors (gcry_mpi_t *factors);
+
+
+/* Check wether the number X is prime. */
+gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
+
+
+
+/************************************
+ * *
+ * Miscellaneous Stuff *
+ * *
+ ************************************/
+
+/* Log levels used by the internal logging facility. */
+enum gcry_log_levels
+ {
+ GCRY_LOG_CONT = 0, /* (Continue the last log line.) */
+ GCRY_LOG_INFO = 10,
+ GCRY_LOG_WARN = 20,
+ GCRY_LOG_ERROR = 30,
+ GCRY_LOG_FATAL = 40,
+ GCRY_LOG_BUG = 50,
+ GCRY_LOG_DEBUG = 100
+ };
+
+/* Type for progress handlers. */
+typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int);
+
+/* Type for memory allocation handlers. */
+typedef void *(*gcry_handler_alloc_t) (size_t n);
+
+/* Type for secure memory check handlers. */
+typedef int (*gcry_handler_secure_check_t) (const void *);
+
+/* Type for memory reallocation handlers. */
+typedef void *(*gcry_handler_realloc_t) (void *p, size_t n);
+
+/* Type for memory free handlers. */
+typedef void (*gcry_handler_free_t) (void *);
+
+/* Type for out-of-memory handlers. */
+typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int);
+
+/* Type for fatal error handlers. */
+typedef void (*gcry_handler_error_t) (void *, int, const char *);
+
+/* Type for logging handlers. */
+typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list);
+
+/* Certain operations can provide progress information. This function
+ is used to register a handler for retrieving these information. */
+void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data);
+
+
+/* Register a custom memory allocation functions. */
+void gcry_set_allocation_handler (
+ gcry_handler_alloc_t func_alloc,
+ gcry_handler_alloc_t func_alloc_secure,
+ gcry_handler_secure_check_t func_secure_check,
+ gcry_handler_realloc_t func_realloc,
+ gcry_handler_free_t func_free);
+
+/* Register a function used instead of the internal out of memory
+ handler. */
+void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque);
+
+/* Register a function used instead of the internal fatal error
+ handler. */
+void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque);
+
+/* Register a function used instead of the internal logging
+ facility. */
+void gcry_set_log_handler (gcry_handler_log_t f, void *opaque);
+
+/* Reserved for future use. */
+void gcry_set_gettext_handler (const char *(*f)(const char*));
+
+/* Libgcrypt uses its own memory allocation. It is important to use
+ gcry_free () to release memory allocated by libgcrypt. */
+void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_realloc (void *a, size_t n);
+char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xrealloc (void *a, size_t n);
+char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC;
+void gcry_free (void *a);
+
+/* Return true if A is allocated in "secure" memory. */
+int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
+
+/* Return true if Libgcrypt is in FIPS mode. */
+#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+
+
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* _GCRYPT_H */
+/*
+@emacs_local_vars_begin@
+@emacs_local_vars_read_only@
+@emacs_local_vars_end@
+*/
diff --git a/grub-core/lib/libgcrypt/src/gcryptrnd.c b/grub-core/lib/libgcrypt/src/gcryptrnd.c
new file mode 100644
index 0000000..b13931b
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/gcryptrnd.c
@@ -0,0 +1,680 @@
+/* gcryptrnd.c - Libgcrypt Random Number Daemon
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * Gcryptend is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Gcryptrnd is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* We require vsyslog pth
+ We need to test for: setrlimit
+
+ We should also prioritize requests. This is best done by putting
+ the requests into queues and have a main thread processing these
+ queues.
+
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pth.h>
+#include <gcrypt.h>
+
+#define PGM "gcryptrnd"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+/* Pth wrapper function definitions. */
+GCRY_THREAD_OPTION_PTH_IMPL;
+
+
+/* Flag set to true if we have been daemonized. */
+static int running_detached;
+/* Flag indicating that a shutdown has been requested. */
+static int shutdown_pending;
+/* Counter for active connections. */
+static int active_connections;
+
+
+
+/* Local prototypes. */
+static void serve (int listen_fd);
+
+
+
+
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+ macros may be used instead. */
+#define wipememory2(_ptr,_set,_len) do { \
+ volatile char *_vptr=(volatile char *)(_ptr); \
+ size_t _vlen=(_len); \
+ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+ } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+
+
+
+/* Error printing utility. PRIORITY should be one of syslog's
+ priority levels. This functions prints to the stderr or syslog
+ depending on whether we are already daemonized. */
+static void
+logit (int priority, const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ if (running_detached)
+ {
+ vsyslog (priority, format, arg_ptr);
+ }
+ else
+ {
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ }
+ va_end (arg_ptr);
+}
+
+/* Callback used by libgcrypt for logging. */
+static void
+my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr)
+{
+ (void)dummy;
+
+ /* Map the log levels. */
+ switch (level)
+ {
+ case GCRY_LOG_CONT: level = LOG_INFO /* FIXME */; break;
+ case GCRY_LOG_INFO: level = LOG_INFO; break;
+ case GCRY_LOG_WARN: level = LOG_WARNING; break;
+ case GCRY_LOG_ERROR:level = LOG_ERR; break;
+ case GCRY_LOG_FATAL:level = LOG_CRIT; break;
+ case GCRY_LOG_BUG: level = LOG_CRIT; break;
+ case GCRY_LOG_DEBUG:level = LOG_DEBUG; break;
+ default: level = LOG_ERR; break;
+ }
+ if (running_detached)
+ {
+ vsyslog (level, format, arg_ptr);
+ }
+ else
+ {
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ if (!*format || format[strlen (format)-1] != '\n')
+ putc ('\n', stderr);
+ }
+}
+
+
+/* The cleanup handler - used to wipe out the secure memory. */
+static void
+cleanup (void)
+{
+ gcry_control (GCRYCTL_TERM_SECMEM );
+}
+
+
+/* Make us a daemon and open the syslog. */
+static void
+daemonize (void)
+{
+ int i;
+ pid_t pid;
+
+ fflush (NULL);
+
+ pid = fork ();
+ if (pid == (pid_t)-1)
+ {
+ logit (LOG_CRIT, "fork failed: %s", strerror (errno));
+ exit (1);
+ }
+ if (pid)
+ exit (0);
+
+ if (setsid() == -1)
+ {
+ logit (LOG_CRIT, "setsid() failed: %s", strerror(errno));
+ exit (1);
+ }
+
+ signal (SIGHUP, SIG_IGN);
+
+ pid = fork ();
+ if (pid == (pid_t)-1)
+ {
+ logit (LOG_CRIT, PGM ": second fork failed: %s", strerror (errno));
+ exit (1);
+ }
+ if (pid)
+ exit (0); /* First child exits. */
+
+ running_detached = 1;
+
+ if (chdir("/"))
+ {
+ logit (LOG_CRIT, "chdir(\"/\") failed: %s", strerror (errno));
+ exit (1);
+ }
+ umask (0);
+
+ for (i=0; i <= 2; i++)
+ close (i);
+
+ openlog (PGM, LOG_PID, LOG_DAEMON);
+}
+
+
+static void
+disable_core_dumps (void)
+{
+#ifdef HAVE_SETRLIMIT
+ struct rlimit limit;
+
+ if (getrlimit (RLIMIT_CORE, &limit))
+ limit.rlim_max = 0;
+ limit.rlim_cur = 0;
+ if( !setrlimit (RLIMIT_CORE, &limit) )
+ return 0;
+ if (errno != EINVAL && errno != ENOSYS)
+ logit (LOG_ERR, "can't disable core dumps: %s\n", strerror (errno));
+#endif /* HAVE_SETRLIMIT */
+}
+
+
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2006 Free Software Foundation, Inc.\n"
+ "License GPLv2+: GNU GPL version 2 or later "
+ "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] [SOCKETNAME]\n"
+ "Start Libgcrypt's random number daemon listening"
+ " on socket SOCKETNAME\n"
+ "SOCKETNAME defaults to XXX\n"
+ "\n"
+ " --no-detach do not deatach from the console\n"
+ " --version print version of the program and exit\n"
+ " --help display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] [SOCKETNAME]\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int no_detach = 0;
+ gpg_error_t err;
+ struct sockaddr_un *srvr_addr;
+ socklen_t addrlen;
+ int fd;
+ int rc;
+ const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
+
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--no-detach"))
+ {
+ no_detach = 1;
+ argc--; argv++;
+ }
+ else
+ print_usage ();
+ }
+
+ if (argc == 1)
+ socketname = argv[0];
+ else if (argc > 1)
+ print_usage ();
+
+ if (!no_detach)
+ daemonize ();
+
+ signal (SIGPIPE, SIG_IGN);
+
+ logit (LOG_NOTICE, "started version " VERSION );
+
+ /* Libgcrypt requires us to register the threading model before we
+ do anything else with it. Note that this also calls pth_init. We
+ do the initialization while already running as a daemon to avoid
+ overhead with double initialization of Libgcrypt. */
+ err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
+ if (err)
+ {
+ logit (LOG_CRIT, "can't register GNU Pth with Libgcrypt: %s",
+ gpg_strerror (err));
+ exit (1);
+ }
+
+ /* Check that the libgcrypt version is sufficient. */
+ if (!gcry_check_version (VERSION) )
+ {
+ logit (LOG_CRIT, "libgcrypt is too old (need %s, have %s)",
+ VERSION, gcry_check_version (NULL) );
+ exit (1);
+ }
+
+ /* Register the logging callback and tell Libcgrypt to put the
+ random pool into secure memory. */
+ gcry_set_log_handler (my_gcry_logger, NULL);
+ gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
+
+ /* Obviously we don't want to allow any core dumps. */
+ disable_core_dumps ();
+
+ /* Initialize the secure memory stuff which will also drop any extra
+ privileges we have. */
+ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+ /* Register a cleanup handler. */
+ atexit (cleanup);
+
+ /* Create and listen on the socket. */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ logit (LOG_CRIT, "can't create socket: %s", strerror (errno));
+ exit (1);
+ }
+ srvr_addr = gcry_xmalloc (sizeof *srvr_addr);
+ memset (srvr_addr, 0, sizeof *srvr_addr);
+ srvr_addr->sun_family = AF_UNIX;
+ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
+ {
+ logit (LOG_CRIT, "socket name `%s' too long", socketname);
+ exit (1);
+ }
+ strcpy (srvr_addr->sun_path, socketname);
+ addrlen = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (srvr_addr->sun_path) + 1);
+ rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
+ if (rc == -1 && errno == EADDRINUSE)
+ {
+ remove (socketname);
+ rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
+ }
+ if (rc == -1)
+ {
+ logit (LOG_CRIT, "error binding socket to `%s': %s",
+ srvr_addr->sun_path, strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ if (listen (fd, 5 ) == -1)
+ {
+ logit (LOG_CRIT, "listen() failed: %s", strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ logit (LOG_INFO, "listening on socket `%s', fd=%d",
+ srvr_addr->sun_path, fd);
+
+ serve (fd);
+ close (fd);
+
+ logit (LOG_NOTICE, "stopped version " VERSION );
+ return 0;
+}
+
+
+/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
+ success or another value on write error. */
+static int
+writen (int fd, const void *buffer, size_t length)
+{
+ while (length)
+ {
+ ssize_t n = pth_write (fd, buffer, length);
+ if (n < 0)
+ {
+ logit (LOG_ERR, "connection %d: write error: %s",
+ fd, strerror (errno));
+ return -1; /* write error */
+ }
+ length -= n;
+ buffer = (const char*)buffer + n;
+ }
+ return 0; /* Okay */
+}
+
+
+/* Send an error response back. Returns 0 on success. */
+static int
+send_error (int fd, int errcode)
+{
+ unsigned char buf[2];
+
+ buf[0] = errcode;
+ buf[1] = 0;
+ return writen (fd, buf, 2 );
+}
+
+/* Send a pong response back. Returns 0 on success or another value
+ on write error. */
+static int
+send_pong (int fd)
+{
+ return writen (fd, "\x00\x04pong", 6);
+}
+
+/* Send a nonce of size LENGTH back. Return 0 on success. */
+static int
+send_nonce (int fd, int length)
+{
+ unsigned char buf[2+255];
+ int rc;
+
+ assert (length >= 0 && length <= 255);
+ buf[0] = 0;
+ buf[1] = length;
+ gcry_create_nonce (buf+2, length);
+ rc = writen (fd, buf, 2+length );
+ wipememory (buf+2, length);
+ return rc;
+}
+
+/* Send a random of size LENGTH with quality LEVEL back. Return 0 on
+ success. */
+static int
+send_random (int fd, int length, int level)
+{
+ unsigned char buf[2+255];
+ int rc;
+
+ assert (length >= 0 && length <= 255);
+ assert (level == GCRY_STRONG_RANDOM || level == GCRY_VERY_STRONG_RANDOM);
+ buf[0] = 0;
+ buf[1] = length;
+ /* Note that we don't bother putting the random stuff into secure
+ memory because this daemon is anyway intended to be run under
+ root and it is questionable whether the kernel buffers etc. are
+ equally well protected. */
+ gcry_randomize (buf+2, length, level);
+ rc = writen (fd, buf, 2+length );
+ wipememory (buf+2, length);
+ return rc;
+}
+
+/* Main processing loop for a connection.
+
+ A request is made up of:
+
+ 1 byte Total length of request; must be 3
+ 1 byte Command
+ 0 = Ping
+ 10 = GetNonce
+ 11 = GetStrongRandom
+ 12 = GetVeryStrongRandom
+ (all other values are reserved)
+ 1 byte Number of requested bytes.
+ This is ignored for command Ping.
+
+ A response is made up of:
+
+ 1 byte Error Code
+ 0 = Everything is fine
+ 1 = Bad Command
+ 0xff = Other error.
+ (For a bad request the connection will simply be closed)
+ 1 byte Length of data
+ n byte data
+
+ The requests are read as long as the connection is open.
+
+
+ */
+static void
+connection_loop (int fd)
+{
+ unsigned char request[3];
+ unsigned char *p;
+ int nleft, n;
+ int rc;
+
+ for (;;)
+ {
+ for (nleft=3, p=request; nleft > 0; )
+ {
+ n = pth_read (fd, p, nleft);
+ if (!n && p == request)
+ return; /* Client terminated connection. */
+ if (n <= 0)
+ {
+ logit (LOG_ERR, "connection %d: read error: %s",
+ fd, n? strerror (errno) : "Unexpected EOF");
+ return;
+ }
+ p += n;
+ nleft -= n;
+ }
+ if (request[0] != 3)
+ {
+ logit (LOG_ERR, "connection %d: invalid length (%d) of request",
+ fd, request[0]);
+ return;
+ }
+
+ switch (request[1])
+ {
+ case 0: /* Ping */
+ rc = send_pong (fd);
+ break;
+ case 10: /* GetNonce */
+ rc = send_nonce (fd, request[2]);
+ break;
+ case 11: /* GetStrongRandom */
+ rc = send_random (fd, request[2], GCRY_STRONG_RANDOM);
+ break;
+ case 12: /* GetVeryStrongRandom */
+ rc = send_random (fd, request[2], GCRY_VERY_STRONG_RANDOM);
+ break;
+
+ default: /* Invalid command */
+ rc = send_error (fd, 1);
+ break;
+ }
+ if (rc)
+ break; /* A write error occurred while sending the response. */
+ }
+}
+
+
+
+/* Entry point for a connection's thread. */
+static void *
+connection_thread (void *arg)
+{
+ int fd = (int)arg;
+
+ active_connections++;
+ logit (LOG_INFO, "connection handler for fd %d started", fd);
+
+ connection_loop (fd);
+
+ close (fd);
+ logit (LOG_INFO, "connection handler for fd %d terminated", fd);
+ active_connections--;
+
+ return NULL;
+}
+
+
+/* This signal handler is called from the main loop between acepting
+ connections. It is called on the regular stack, thus no special
+ caution needs to be taken. It returns true to indicate that the
+ process should terminate. */
+static int
+handle_signal (int signo)
+{
+ switch (signo)
+ {
+ case SIGHUP:
+ logit (LOG_NOTICE, "SIGHUP received - re-reading configuration");
+ break;
+
+ case SIGUSR1:
+ logit (LOG_NOTICE, "SIGUSR1 received - no action defined");
+ break;
+
+ case SIGUSR2:
+ logit (LOG_NOTICE, "SIGUSR2 received - no action defined");
+ break;
+
+ case SIGTERM:
+ if (!shutdown_pending)
+ logit (LOG_NOTICE, "SIGTERM received - shutting down ...");
+ else
+ logit (LOG_NOTICE, "SIGTERM received - still %d active connections",
+ active_connections);
+ shutdown_pending++;
+ if (shutdown_pending > 2)
+ {
+ logit (LOG_NOTICE, "shutdown forced");
+ return 1;
+ }
+ break;
+
+ case SIGINT:
+ logit (LOG_NOTICE, "SIGINT received - immediate shutdown");
+ return 1;
+
+ default:
+ logit (LOG_NOTICE, "signal %d received - no action defined\n", signo);
+ }
+ return 0;
+}
+
+
+
+/* Main server loop. This is called with the FD of the listening
+ socket. */
+static void
+serve (int listen_fd)
+{
+ pth_attr_t tattr;
+ pth_event_t ev;
+ sigset_t sigs;
+ int signo;
+ struct sockaddr_un paddr;
+ socklen_t plen = sizeof (paddr);
+ int fd;
+
+ tattr = pth_attr_new();
+ pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
+ pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
+ pth_attr_set (tattr, PTH_ATTR_NAME, "connection");
+
+ sigemptyset (&sigs);
+ sigaddset (&sigs, SIGHUP);
+ sigaddset (&sigs, SIGUSR1);
+ sigaddset (&sigs, SIGUSR2);
+ sigaddset (&sigs, SIGINT);
+ sigaddset (&sigs, SIGTERM);
+ ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
+
+ for (;;)
+ {
+ if (shutdown_pending)
+ {
+ if (!active_connections)
+ break; /* Ready. */
+
+ /* Do not accept anymore connections but wait for existing
+ connections to terminate. */
+ signo = 0;
+ pth_wait (ev);
+ if (pth_event_occurred (ev) && signo)
+ if (handle_signal (signo))
+ break; /* Stop the loop. */
+ continue;
+ }
+
+ gcry_fast_random_poll ();
+ fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
+ if (fd == -1)
+ {
+ if (pth_event_occurred (ev))
+ {
+ if (handle_signal (signo))
+ break; /* Stop the loop. */
+ continue;
+ }
+ logit (LOG_WARNING, "accept failed: %s - waiting 1s\n",
+ strerror (errno));
+ gcry_fast_random_poll ();
+ pth_sleep (1);
+ continue;
+ }
+
+ if (!pth_spawn (tattr, connection_thread, (void*)fd))
+ {
+ logit (LOG_ERR, "error spawning connection handler: %s\n",
+ strerror (errno) );
+ close (fd);
+ }
+ }
+
+ pth_event_free (ev, PTH_FREE_ALL);
+}
diff --git a/grub-core/lib/libgcrypt/src/getrandom.c b/grub-core/lib/libgcrypt/src/getrandom.c
new file mode 100644
index 0000000..f9bb5c0
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/getrandom.c
@@ -0,0 +1,326 @@
+/* getrandom.c - Libgcrypt Random Number client
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * Getrandom is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Getrandom is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define PGM "getrandom"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+
+static void
+logit (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ va_end (arg_ptr);
+}
+
+
+/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
+ success or another value on write error. */
+static int
+writen (int fd, const void *buffer, size_t length)
+{
+ while (length)
+ {
+ ssize_t n;
+
+ do
+ n = write (fd, buffer, length);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("write error: %s", strerror (errno));
+ return -1; /* write error */
+ }
+ length -= n;
+ buffer = (const char *)buffer + n;
+ }
+ return 0; /* Okay */
+}
+
+
+
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2006 Free Software Foundation, Inc.\n"
+ "License GPLv2+: GNU GPL version 2 or later "
+ "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] NBYTES\n"
+ "Connect to libgcrypt's random number daemon and "
+ "return random numbers"
+ "\n"
+ " --nonce Return weak random suitable for a nonce\n"
+ " --very-strong Return very strong random\n"
+ " --ping Send a ping\n"
+ " --socket NAME Name of sockket to connect to\n"
+ " --hex Return result as a hex dump\n"
+ " --verbose Show what we are doing\n"
+ " --version Print version of the program and exit\n"
+ " --help Display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ struct sockaddr_un *srvr_addr;
+ socklen_t addrlen;
+ int fd;
+ int rc;
+ unsigned char buffer[300];
+ int nleft, nread;
+ const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
+ int do_ping = 0;
+ int get_nonce = 0;
+ int get_very_strong = 0;
+ int req_nbytes, nbytes, n;
+ int verbose = 0;
+ int fail = 0;
+ int do_hex = 0;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--socket") && argc > 1 )
+ {
+ argc--; argv++;
+ socketname = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--nonce"))
+ {
+ argc--; argv++;
+ get_nonce = 1;
+ }
+ else if (!strcmp (*argv, "--very-strong"))
+ {
+ argc--; argv++;
+ get_very_strong = 1;
+ }
+ else if (!strcmp (*argv, "--ping"))
+ {
+ argc--; argv++;
+ do_ping = 1;
+ }
+ else if (!strcmp (*argv, "--hex"))
+ {
+ argc--; argv++;
+ do_hex = 1;
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ argc--; argv++;
+ verbose = 1;
+ }
+ else
+ print_usage ();
+ }
+
+
+ if (!argc && do_ping)
+ ; /* This is allowed. */
+ else if (argc != 1)
+ print_usage ();
+ req_nbytes = argc? atoi (*argv) : 0;
+
+ if (req_nbytes < 0)
+ print_usage ();
+
+ /* Create a socket. */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ logit ("can't create socket: %s", strerror (errno));
+ exit (1);
+ }
+ srvr_addr = malloc (sizeof *srvr_addr);
+ if (!srvr_addr)
+ {
+ logit ("malloc failed: %s", strerror (errno));
+ exit (1);
+ }
+ memset (srvr_addr, 0, sizeof *srvr_addr);
+ srvr_addr->sun_family = AF_UNIX;
+ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
+ {
+ logit ("socket name `%s' too long", socketname);
+ exit (1);
+ }
+ strcpy (srvr_addr->sun_path, socketname);
+ addrlen = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (srvr_addr->sun_path) + 1);
+ rc = connect (fd, (struct sockaddr*) srvr_addr, addrlen);
+ if (rc == -1)
+ {
+ logit ("error connecting socket `%s': %s",
+ srvr_addr->sun_path, strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ do
+ {
+ nbytes = req_nbytes > 255? 255 : req_nbytes;
+ req_nbytes -= nbytes;
+
+ buffer[0] = 3;
+ if (do_ping)
+ buffer[1] = 0;
+ else if (get_nonce)
+ buffer[1] = 10;
+ else if (get_very_strong)
+ buffer[1] = 12;
+ else
+ buffer[1] = 11;
+ buffer[2] = nbytes;
+ if (writen (fd, buffer, 3))
+ fail = 1;
+ else
+ {
+ for (nleft=2, nread=0; nleft > 0; )
+ {
+ do
+ n = read (fd, buffer+nread, nleft);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("read error: %s", strerror (errno));
+ exit (1);
+ }
+ nleft -= n;
+ nread += n;
+ if (nread && buffer[0])
+ {
+ logit ("server returned error code %d", buffer[0]);
+ exit (1);
+ }
+ }
+ if (verbose)
+ logit ("received response with %d bytes of data", buffer[1]);
+ if (buffer[1] < nbytes)
+ {
+ logit ("warning: server returned less bytes than requested");
+ fail = 1;
+ }
+ else if (buffer[1] > nbytes && !do_ping)
+ {
+ logit ("warning: server returned more bytes than requested");
+ fail = 1;
+ }
+ nbytes = buffer[1];
+ if (nbytes > sizeof buffer)
+ {
+ logit ("buffer too short to receive data");
+ exit (1);
+ }
+
+ for (nleft=nbytes, nread=0; nleft > 0; )
+ {
+ do
+ n = read (fd, buffer+nread, nleft);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("read error: %s", strerror (errno));
+ exit (1);
+ }
+ nleft -= n;
+ nread += n;
+ }
+
+ if (do_hex)
+ {
+ for (n=0; n < nbytes; n++)
+ {
+ if (!n)
+ ;
+ else if (!(n % 16))
+ putchar ('\n');
+ else
+ putchar (' ');
+ printf ("%02X", buffer[n]);
+ }
+ if (nbytes)
+ putchar ('\n');
+ }
+ else
+ {
+ if (fwrite (buffer, nbytes, 1, stdout) != 1)
+ {
+ logit ("error writing to stdout: %s", strerror (errno));
+ fail = 1;
+ }
+ }
+ }
+ }
+ while (!fail && req_nbytes);
+
+ close (fd);
+ free (srvr_addr);
+ return fail? 1 : 0;
+}
diff --git a/grub-core/lib/libgcrypt/src/global.c b/grub-core/lib/libgcrypt/src/global.c
new file mode 100644
index 0000000..36d6646
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/global.c
@@ -0,0 +1,1112 @@
+/* global.c - global control functions
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2004, 2005, 2006, 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "stdmem.h" /* our own memory allocator */
+#include "secmem.h" /* our own secmem allocator */
+#include "ath.h"
+
+
+
+/****************
+ * flag bits: 0 : general cipher debug
+ * 1 : general MPI debug
+ */
+static unsigned int debug_flags;
+
+/* gcry_control (GCRYCTL_SET_FIPS_MODE), sets this flag so that the
+ initialization code switched fips mode on. */
+static int force_fips_mode;
+
+/* Controlled by global_init(). */
+static int any_init_done;
+
+/* A table to map hardware features to a string. */
+static struct
+{
+ unsigned int flag;
+ const char *desc;
+} hwflist[] =
+ {
+ { HWF_PADLOCK_RNG, "padlock-rng" },
+ { HWF_PADLOCK_AES, "padlock-aes" },
+ { HWF_PADLOCK_SHA, "padlock-sha" },
+ { HWF_PADLOCK_MMUL,"padlock-mmul"},
+ { HWF_INTEL_AESNI, "intel-aesni" },
+ { 0, NULL}
+ };
+
+/* A bit vector with the hardware features which shall not be used.
+ This variable must be set prior to any initialization. */
+static unsigned int disabled_hw_features;
+
+
+/* Memory management. */
+
+static gcry_handler_alloc_t alloc_func;
+static gcry_handler_alloc_t alloc_secure_func;
+static gcry_handler_secure_check_t is_secure_func;
+static gcry_handler_realloc_t realloc_func;
+static gcry_handler_free_t free_func;
+static gcry_handler_no_mem_t outofcore_handler;
+static void *outofcore_handler_value;
+static int no_secure_memory;
+
+
+
+
+
+/* This is our handmade constructor. It gets called by any function
+ likely to be called at startup. The suggested way for an
+ application to make sure that this has been called is by using
+ gcry_check_version. */
+static void
+global_init (void)
+{
+ gcry_error_t err = 0;
+
+ if (any_init_done)
+ return;
+ any_init_done = 1;
+
+ /* Initialize our portable thread/mutex wrapper. */
+ err = ath_init ();
+ if (err)
+ {
+ err = gpg_error_from_errno (err);
+ goto fail;
+ }
+
+ /* See whether the system is in FIPS mode. This needs to come as
+ early as possible but after ATH has been initialized. */
+ _gcry_initialize_fips_mode (force_fips_mode);
+
+ /* Before we do any other initialization we need to test available
+ hardware features. */
+ _gcry_detect_hw_features (disabled_hw_features);
+
+ /* Initialize the modules - this is mainly allocating some memory and
+ creating mutexes. */
+ err = _gcry_cipher_init ();
+ if (err)
+ goto fail;
+ err = _gcry_md_init ();
+ if (err)
+ goto fail;
+ err = _gcry_pk_init ();
+ if (err)
+ goto fail;
+ err = _gcry_primegen_init ();
+ if (err)
+ goto fail;
+
+ return;
+
+ fail:
+ BUG ();
+}
+
+
+/* This function is called by the macro fips_is_operational and makes
+ sure that the minimal initialization has been done. This is far
+ from a perfect solution and hides problems with an improper
+ initialization but at least in single-threaded mode it should work
+ reliable.
+
+ The reason we need this is that a lot of applications don't use
+ Libgcrypt properly by not running any initialization code at all.
+ They just call a Libgcrypt function and that is all what they want.
+ Now with the FIPS mode, that has the side effect of entering FIPS
+ mode (for security reasons, FIPS mode is the default if no
+ initialization has been done) and bailing out immediately because
+ the FSM is in the wrong state. If we always run the init code,
+ Libgcrypt can test for FIPS mode and at least if not in FIPS mode,
+ it will behave as before. Note that this on-the-fly initialization
+ is only done for the cryptographic functions subject to FIPS mode
+ and thus not all API calls will do such an initialization. */
+int
+_gcry_global_is_operational (void)
+{
+ if (!any_init_done)
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+ "missing initialization - please fix the application");
+#endif /*HAVE_SYSLOG*/
+ global_init ();
+ }
+ return _gcry_fips_is_operational ();
+}
+
+
+
+
+/* Version number parsing. */
+
+/* This function parses the first portion of the version number S and
+ stores it in *NUMBER. On success, this function returns a pointer
+ into S starting with the first character, which is not part of the
+ initial number portion; on failure, NULL is returned. */
+static const char*
+parse_version_number( const char *s, int *number )
+{
+ int val = 0;
+
+ if( *s == '0' && isdigit(s[1]) )
+ return NULL; /* leading zeros are not allowed */
+ for ( ; isdigit(*s); s++ ) {
+ val *= 10;
+ val += *s - '0';
+ }
+ *number = val;
+ return val < 0? NULL : s;
+}
+
+/* This function breaks up the complete string-representation of the
+ version number S, which is of the following struture: <major
+ number>.<minor number>.<micro number><patch level>. The major,
+ minor and micro number components will be stored in *MAJOR, *MINOR
+ and *MICRO.
+
+ On success, the last component, the patch level, will be returned;
+ in failure, NULL will be returned. */
+
+static const char *
+parse_version_string( const char *s, int *major, int *minor, int *micro )
+{
+ s = parse_version_number( s, major );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, minor );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, micro );
+ if( !s )
+ return NULL;
+ return s; /* patchlevel */
+}
+
+/* If REQ_VERSION is non-NULL, check that the version of the library
+ is at minimum the requested one. Returns the string representation
+ of the library version if the condition is satisfied; return NULL
+ if the requested version is newer than that of the library.
+
+ If a NULL is passed to this function, no check is done, but the
+ string representation of the library is simply returned. */
+const char *
+gcry_check_version( const char *req_version )
+{
+ const char *ver = VERSION;
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl;
+
+ /* Initialize library. */
+ global_init ();
+
+ if ( !req_version )
+ /* Caller wants our version number. */
+ return ver;
+
+ /* Parse own version number. */
+ my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
+ if ( !my_plvl )
+ /* very strange our own version is bogus. Shouldn't we use
+ assert() here and bail out in case this happens? -mo. */
+ return NULL;
+
+ /* Parse requested version number. */
+ if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro))
+ return NULL; /* req version string is invalid, this can happen. */
+
+ /* Compare version numbers. */
+ if ( my_major > rq_major
+ || (my_major == rq_major && my_minor > rq_minor)
+ || (my_major == rq_major && my_minor == rq_minor && my_micro > rq_micro)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro == rq_micro))
+ {
+ return ver;
+ }
+
+ return NULL;
+}
+
+
+static void
+print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
+{
+ unsigned int hwf;
+ int i;
+
+ fnc (fp, "version:%s:\n", VERSION);
+ fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
+ fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
+ fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
+ fnc (fp, "rnd-mod:"
+#if USE_RNDEGD
+ "egd:"
+#endif
+#if USE_RNDLINUX
+ "linux:"
+#endif
+#if USE_RNDUNIX
+ "unix:"
+#endif
+#if USE_RNDW32
+ "w32:"
+#endif
+ "\n");
+ fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
+ fnc (fp, "threads:%s:\n", ath_get_model (NULL));
+ hwf = _gcry_get_hw_features ();
+ fnc (fp, "hwflist:");
+ for (i=0; hwflist[i].desc; i++)
+ if ( (hwf & hwflist[i].flag) )
+ fnc (fp, "%s:", hwflist[i].desc);
+ fnc (fp, "\n");
+ /* We use y/n instead of 1/0 for the simple reason that Emacsen's
+ compile error parser would accidently flag that line when printed
+ during "make check" as an error. */
+ fnc (fp, "fips-mode:%c:%c:\n",
+ fips_mode ()? 'y':'n',
+ _gcry_enforced_fips_mode ()? 'y':'n' );
+}
+
+
+
+
+/* Command dispatcher function, acting as general control
+ function. */
+gcry_error_t
+_gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
+{
+ static int init_finished = 0;
+ gcry_err_code_t err = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_ENABLE_M_GUARD:
+ _gcry_private_enable_m_guard ();
+ break;
+
+ case GCRYCTL_ENABLE_QUICK_RANDOM:
+ _gcry_enable_quick_random_gen ();
+ break;
+
+ case GCRYCTL_FAKED_RANDOM_P:
+ /* Return an error if the RNG is faked one (e.g. enabled by
+ ENABLE_QUICK_RANDOM. */
+ if (_gcry_random_is_faked ())
+ err = GPG_ERR_GENERAL; /* Use as TRUE value. */
+ break;
+
+ case GCRYCTL_DUMP_RANDOM_STATS:
+ _gcry_random_dump_stats ();
+ break;
+
+ case GCRYCTL_DUMP_MEMORY_STATS:
+ /*m_print_stats("[fixme: prefix]");*/
+ break;
+
+ case GCRYCTL_DUMP_SECMEM_STATS:
+ _gcry_secmem_dump_stats ();
+ break;
+
+ case GCRYCTL_DROP_PRIVS:
+ global_init ();
+ _gcry_secmem_init (0);
+ break;
+
+ case GCRYCTL_DISABLE_SECMEM:
+ global_init ();
+ no_secure_memory = 1;
+ break;
+
+ case GCRYCTL_INIT_SECMEM:
+ global_init ();
+ _gcry_secmem_init (va_arg (arg_ptr, unsigned int));
+ if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED))
+ err = GPG_ERR_GENERAL;
+ break;
+
+ case GCRYCTL_TERM_SECMEM:
+ global_init ();
+ _gcry_secmem_term ();
+ break;
+
+ case GCRYCTL_DISABLE_SECMEM_WARN:
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_NO_WARNING));
+ break;
+
+ case GCRYCTL_SUSPEND_SECMEM_WARN:
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_SUSPEND_WARNING));
+ break;
+
+ case GCRYCTL_RESUME_SECMEM_WARN:
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
+ break;
+
+ case GCRYCTL_USE_SECURE_RNDPOOL:
+ global_init ();
+ _gcry_secure_random_alloc (); /* Put random number into secure memory. */
+ break;
+
+ case GCRYCTL_SET_RANDOM_SEED_FILE:
+ _gcry_set_random_seed_file (va_arg (arg_ptr, const char *));
+ break;
+
+ case GCRYCTL_UPDATE_RANDOM_SEED_FILE:
+ if ( fips_is_operational () )
+ _gcry_update_random_seed_file ();
+ break;
+
+ case GCRYCTL_SET_VERBOSITY:
+ _gcry_set_log_verbosity (va_arg (arg_ptr, int));
+ break;
+
+ case GCRYCTL_SET_DEBUG_FLAGS:
+ debug_flags |= va_arg (arg_ptr, unsigned int);
+ break;
+
+ case GCRYCTL_CLEAR_DEBUG_FLAGS:
+ debug_flags &= ~va_arg (arg_ptr, unsigned int);
+ break;
+
+ case GCRYCTL_DISABLE_INTERNAL_LOCKING:
+ /* Not used anymore. */
+ global_init ();
+ break;
+
+ case GCRYCTL_ANY_INITIALIZATION_P:
+ if (any_init_done)
+ err = GPG_ERR_GENERAL;
+ break;
+
+ case GCRYCTL_INITIALIZATION_FINISHED_P:
+ if (init_finished)
+ err = GPG_ERR_GENERAL; /* Yes. */
+ break;
+
+ case GCRYCTL_INITIALIZATION_FINISHED:
+ /* This is a hook which should be used by an application after
+ all initialization has been done and right before any threads
+ are started. It is not really needed but the only way to be
+ really sure that all initialization for thread-safety has
+ been done. */
+ if (! init_finished)
+ {
+ global_init ();
+ /* Do only a basic random initialization, i.e. init the
+ mutexes. */
+ _gcry_random_initialize (0);
+ init_finished = 1;
+ /* Force us into operational state if in FIPS mode. */
+ (void)fips_is_operational ();
+ }
+ break;
+
+ case GCRYCTL_SET_THREAD_CBS:
+ err = ath_install (va_arg (arg_ptr, void *));
+ if (!err)
+ global_init ();
+ break;
+
+ case GCRYCTL_FAST_POLL:
+ /* We need to do make sure that the random pool is really
+ initialized so that the poll function is not a NOP. */
+ _gcry_random_initialize (1);
+
+ if ( fips_is_operational () )
+ _gcry_fast_random_poll ();
+ break;
+
+ case GCRYCTL_SET_RNDEGD_SOCKET:
+#if USE_RNDEGD
+ err = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
+#else
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+#endif
+ break;
+
+ case GCRYCTL_SET_RANDOM_DAEMON_SOCKET:
+ _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *));
+ break;
+
+ case GCRYCTL_USE_RANDOM_DAEMON:
+ /* We need to do make sure that the random pool is really
+ initialized so that the poll function is not a NOP. */
+ _gcry_random_initialize (1);
+ _gcry_use_random_daemon (!! va_arg (arg_ptr, int));
+ break;
+
+ /* This command dumps information pertaining to the
+ configuration of libgcrypt to the given stream. It may be
+ used before the initialization has been finished but not
+ before a gcry_version_check. */
+ case GCRYCTL_PRINT_CONFIG:
+ {
+ FILE *fp = va_arg (arg_ptr, FILE *);
+ print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp);
+ }
+ break;
+
+ case GCRYCTL_OPERATIONAL_P:
+ /* Returns true if the library is in an operational state. This
+ is always true for non-fips mode. */
+ if (_gcry_fips_test_operational ())
+ err = GPG_ERR_GENERAL; /* Used as TRUE value */
+ break;
+
+ case GCRYCTL_FIPS_MODE_P:
+ if (fips_mode ()
+ && !_gcry_is_fips_mode_inactive ()
+ && !no_secure_memory)
+ err = GPG_ERR_GENERAL; /* Used as TRUE value */
+ break;
+
+ case GCRYCTL_FORCE_FIPS_MODE:
+ /* Performing this command puts the library into fips mode. If
+ the library has already been initialized into fips mode, a
+ selftest is triggered. It is not possible to put the libraty
+ into fips mode after having passed the initialization. */
+ if (!any_init_done)
+ {
+ /* Not yet intialized at all. Set a flag so that we are put
+ into fips mode during initialization. */
+ force_fips_mode = 1;
+ }
+ else
+ {
+ /* Already initialized. If we are already operational we
+ run a selftest. If not we use the is_operational call to
+ force us into operational state if possible. */
+ if (_gcry_fips_test_error_or_operational ())
+ _gcry_fips_run_selftests (1);
+ if (_gcry_fips_is_operational ())
+ err = GPG_ERR_GENERAL; /* Used as TRUE value */
+ }
+ break;
+
+ case GCRYCTL_SELFTEST:
+ /* Run a selftest. This works in fips mode as well as in
+ standard mode. In contrast to the power-up tests, we use an
+ extended version of the selftests. Returns 0 on success or an
+ error code. */
+ global_init ();
+ err = _gcry_fips_run_selftests (1);
+ break;
+
+#if _GCRY_GCC_VERSION >= 40600
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wswitch"
+#endif
+ case 58: /* Init external random test. */
+ {
+ void **rctx = va_arg (arg_ptr, void **);
+ unsigned int flags = va_arg (arg_ptr, unsigned int);
+ const void *key = va_arg (arg_ptr, const void *);
+ size_t keylen = va_arg (arg_ptr, size_t);
+ const void *seed = va_arg (arg_ptr, const void *);
+ size_t seedlen = va_arg (arg_ptr, size_t);
+ const void *dt = va_arg (arg_ptr, const void *);
+ size_t dtlen = va_arg (arg_ptr, size_t);
+ if (!fips_is_operational ())
+ err = fips_not_operational ();
+ else
+ err = _gcry_random_init_external_test (rctx, flags, key, keylen,
+ seed, seedlen, dt, dtlen);
+ }
+ break;
+ case 59: /* Run external random test. */
+ {
+ void *ctx = va_arg (arg_ptr, void *);
+ void *buffer = va_arg (arg_ptr, void *);
+ size_t buflen = va_arg (arg_ptr, size_t);
+ if (!fips_is_operational ())
+ err = fips_not_operational ();
+ else
+ err = _gcry_random_run_external_test (ctx, buffer, buflen);
+ }
+ break;
+ case 60: /* Deinit external random test. */
+ {
+ void *ctx = va_arg (arg_ptr, void *);
+ _gcry_random_deinit_external_test (ctx);
+ }
+ break;
+ case 61: /* RFU */
+ break;
+ case 62: /* RFU */
+ break;
+#if _GCRY_GCC_VERSION >= 40600
+# pragma GCC diagnostic pop
+#endif
+
+ case GCRYCTL_DISABLE_HWF:
+ {
+ const char *name = va_arg (arg_ptr, const char *);
+ int i;
+
+ for (i=0; hwflist[i].desc; i++)
+ if (!strcmp (hwflist[i].desc, name))
+ {
+ disabled_hw_features |= hwflist[i].flag;
+ break;
+ }
+ if (!hwflist[i].desc)
+ err = GPG_ERR_INV_NAME;
+ }
+ break;
+
+ default:
+ /* A call to make sure that the dummy code is linked in. */
+ _gcry_compat_identification ();
+ err = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (err);
+}
+
+
+/* Command dispatcher function, acting as general control
+ function. */
+gcry_error_t
+gcry_control (enum gcry_ctl_cmds cmd, ...)
+{
+ gcry_error_t err;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, cmd);
+ err = _gcry_vcontrol (cmd, arg_ptr);
+ va_end(arg_ptr);
+ return err;
+}
+
+
+
+/* Return a pointer to a string containing a description of the error
+ code in the error value ERR. */
+const char *
+gcry_strerror (gcry_error_t err)
+{
+ return gpg_strerror (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+ source in the error value ERR. */
+const char *
+gcry_strsource (gcry_error_t err)
+{
+ return gpg_strsource (err);
+}
+
+/* Retrieve the error code for the system error ERR. This returns
+ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+ this). */
+gcry_err_code_t
+gcry_err_code_from_errno (int err)
+{
+ return gpg_err_code_from_errno (err);
+}
+
+
+/* Retrieve the system error for the error code CODE. This returns 0
+ if CODE is not a system error code. */
+int
+gcry_err_code_to_errno (gcry_err_code_t code)
+{
+ return gpg_err_code_from_errno (code);
+}
+
+
+/* Return an error value with the error source SOURCE and the system
+ error ERR. */
+gcry_error_t
+gcry_err_make_from_errno (gpg_err_source_t source, int err)
+{
+ return gpg_err_make_from_errno (source, err);
+}
+
+
+/* Return an error value with the system error ERR. */
+gcry_err_code_t
+gcry_error_from_errno (int err)
+{
+ return gcry_error (gpg_err_code_from_errno (err));
+}
+
+
+/* Set custom allocation handlers. This is in general not useful
+ * because the libgcrypt allocation functions are guaranteed to
+ * provide proper allocation handlers which zeroize memory if needed.
+ * NOTE: All 5 functions should be set. */
+void
+gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
+ gcry_handler_alloc_t new_alloc_secure_func,
+ gcry_handler_secure_check_t new_is_secure_func,
+ gcry_handler_realloc_t new_realloc_func,
+ gcry_handler_free_t new_free_func)
+{
+ global_init ();
+
+ if (fips_mode ())
+ {
+ /* We do not want to enforce the fips mode, but merely set a
+ flag so that the application may check whether it is still in
+ fips mode. */
+ _gcry_inactivate_fips_mode ("custom allocation handler");
+ }
+
+ alloc_func = new_alloc_func;
+ alloc_secure_func = new_alloc_secure_func;
+ is_secure_func = new_is_secure_func;
+ realloc_func = new_realloc_func;
+ free_func = new_free_func;
+}
+
+
+
+/****************
+ * Set an optional handler which is called in case the xmalloc functions
+ * ran out of memory. This handler may do one of these things:
+ * o free some memory and return true, so that the xmalloc function
+ * tries again.
+ * o Do whatever it like and return false, so that the xmalloc functions
+ * use the default fatal error handler.
+ * o Terminate the program and don't return.
+ *
+ * The handler function is called with 3 arguments: The opaque value set with
+ * this function, the requested memory size, and a flag with these bits
+ * currently defined:
+ * bit 0 set = secure memory has been requested.
+ */
+void
+gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ),
+ void *value )
+{
+ global_init ();
+
+ if (fips_mode () )
+ {
+ log_info ("out of core handler ignored in FIPS mode\n");
+ return;
+ }
+
+ outofcore_handler = f;
+ outofcore_handler_value = value;
+}
+
+/* Return the no_secure_memory flag. */
+static int
+get_no_secure_memory (void)
+{
+ if (!no_secure_memory)
+ return 0;
+ if (_gcry_enforced_fips_mode ())
+ {
+ no_secure_memory = 0;
+ return 0;
+ }
+ return no_secure_memory;
+}
+
+
+static gcry_err_code_t
+do_malloc (size_t n, unsigned int flags, void **mem)
+{
+ gcry_err_code_t err = 0;
+ void *m;
+
+ if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ())
+ {
+ if (alloc_secure_func)
+ m = (*alloc_secure_func) (n);
+ else
+ m = _gcry_private_malloc_secure (n);
+ }
+ else
+ {
+ if (alloc_func)
+ m = (*alloc_func) (n);
+ else
+ m = _gcry_private_malloc (n);
+ }
+
+ if (!m)
+ {
+ /* Make sure that ERRNO has been set in case a user supplied
+ memory handler didn't it correctly. */
+ if (!errno)
+ gpg_err_set_errno (ENOMEM);
+ err = gpg_err_code_from_errno (errno);
+ }
+ else
+ *mem = m;
+
+ return err;
+}
+
+void *
+gcry_malloc (size_t n)
+{
+ void *mem = NULL;
+
+ do_malloc (n, 0, &mem);
+
+ return mem;
+}
+
+void *
+gcry_malloc_secure (size_t n)
+{
+ void *mem = NULL;
+
+ do_malloc (n, GCRY_ALLOC_FLAG_SECURE, &mem);
+
+ return mem;
+}
+
+int
+gcry_is_secure (const void *a)
+{
+ if (get_no_secure_memory ())
+ return 0;
+ if (is_secure_func)
+ return is_secure_func (a) ;
+ return _gcry_private_is_secure (a);
+}
+
+void
+_gcry_check_heap( const void *a )
+{
+ (void)a;
+
+ /* FIXME: implement this*/
+#if 0
+ if( some_handler )
+ some_handler(a)
+ else
+ _gcry_private_check_heap(a)
+#endif
+}
+
+void *
+gcry_realloc (void *a, size_t n)
+{
+ void *p;
+
+ /* To avoid problems with non-standard realloc implementations and
+ our own secmem_realloc, we divert to malloc and free here. */
+ if (!a)
+ return gcry_malloc (n);
+ if (!n)
+ {
+ gcry_free (a);
+ return NULL;
+ }
+
+ if (realloc_func)
+ p = realloc_func (a, n);
+ else
+ p = _gcry_private_realloc (a, n);
+ if (!p && !errno)
+ gpg_err_set_errno (ENOMEM);
+ return p;
+}
+
+void
+gcry_free (void *p)
+{
+ int save_errno;
+
+ if (!p)
+ return;
+
+ /* In case ERRNO is set we better save it so that the free machinery
+ may not accidently change ERRNO. We restore it only if it was
+ already set to comply with the usual C semantic for ERRNO. */
+ save_errno = errno;
+ if (free_func)
+ free_func (p);
+ else
+ _gcry_private_free (p);
+
+ if (save_errno)
+ gpg_err_set_errno (save_errno);
+}
+
+void *
+gcry_calloc (size_t n, size_t m)
+{
+ size_t bytes;
+ void *p;
+
+ bytes = n * m; /* size_t is unsigned so the behavior on overflow is
+ defined. */
+ if (m && bytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+
+ p = gcry_malloc (bytes);
+ if (p)
+ memset (p, 0, bytes);
+ return p;
+}
+
+void *
+gcry_calloc_secure (size_t n, size_t m)
+{
+ size_t bytes;
+ void *p;
+
+ bytes = n * m; /* size_t is unsigned so the behavior on overflow is
+ defined. */
+ if (m && bytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+
+ p = gcry_malloc_secure (bytes);
+ if (p)
+ memset (p, 0, bytes);
+ return p;
+}
+
+
+/* Create and return a copy of the null-terminated string STRING. If
+ it is contained in secure memory, the copy will be contained in
+ secure memory as well. In an out-of-memory condition, NULL is
+ returned. */
+char *
+gcry_strdup (const char *string)
+{
+ char *string_cp = NULL;
+ size_t string_n = 0;
+
+ string_n = strlen (string);
+
+ if (gcry_is_secure (string))
+ string_cp = gcry_malloc_secure (string_n + 1);
+ else
+ string_cp = gcry_malloc (string_n + 1);
+
+ if (string_cp)
+ strcpy (string_cp, string);
+
+ return string_cp;
+}
+
+
+void *
+gcry_xmalloc( size_t n )
+{
+ void *p;
+
+ while ( !(p = gcry_malloc( n )) )
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, 0) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL);
+ }
+ }
+ return p;
+}
+
+void *
+gcry_xrealloc( void *a, size_t n )
+{
+ void *p;
+
+ while ( !(p = gcry_realloc( a, n )) )
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n,
+ gcry_is_secure(a)? 3:2 ) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL );
+ }
+ }
+ return p;
+}
+
+void *
+gcry_xmalloc_secure( size_t n )
+{
+ void *p;
+
+ while ( !(p = gcry_malloc_secure( n )) )
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, 1) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno),
+ _("out of core in secure memory"));
+ }
+ }
+ return p;
+}
+
+
+void *
+gcry_xcalloc( size_t n, size_t m )
+{
+ size_t nbytes;
+ void *p;
+
+ nbytes = n * m;
+ if (m && nbytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
+ }
+
+ p = gcry_xmalloc ( nbytes );
+ memset ( p, 0, nbytes );
+ return p;
+}
+
+void *
+gcry_xcalloc_secure( size_t n, size_t m )
+{
+ size_t nbytes;
+ void *p;
+
+ nbytes = n * m;
+ if (m && nbytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
+ }
+
+ p = gcry_xmalloc_secure ( nbytes );
+ memset ( p, 0, nbytes );
+ return p;
+}
+
+char *
+gcry_xstrdup (const char *string)
+{
+ char *p;
+
+ while ( !(p = gcry_strdup (string)) )
+ {
+ size_t n = strlen (string);
+ int is_sec = !!gcry_is_secure (string);
+
+ if (fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, is_sec) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno),
+ is_sec? _("out of core in secure memory"):NULL);
+ }
+ }
+
+ return p;
+}
+
+
+int
+_gcry_get_debug_flag (unsigned int mask)
+{
+ if ( fips_mode () )
+ return 0;
+ return (debug_flags & mask);
+}
+
+
+
+/* It is often useful to get some feedback of long running operations.
+ This function may be used to register a handler for this.
+ The callback function CB is used as:
+
+ void cb (void *opaque, const char *what, int printchar,
+ int current, int total);
+
+ Where WHAT is a string identifying the the type of the progress
+ output, PRINTCHAR the character usually printed, CURRENT the amount
+ of progress currently done and TOTAL the expected amount of
+ progress. A value of 0 for TOTAL indicates that there is no
+ estimation available.
+
+ Defined values for WHAT:
+
+ "need_entropy" X 0 number-of-bytes-required
+ When running low on entropy
+ "primegen" '\n' 0 0
+ Prime generated
+ '!'
+ Need to refresh the prime pool
+ '<','>'
+ Number of bits adjusted
+ '^'
+ Looking for a generator
+ '.'
+ Fermat tests on 10 candidates failed
+ ':'
+ Restart with a new random value
+ '+'
+ Rabin Miller test passed
+ "pk_elg" '+','-','.','\n' 0 0
+ Only used in debugging mode.
+ "pk_dsa"
+ Only used in debugging mode.
+*/
+void
+gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
+ void *cb_data)
+{
+#if USE_DSA
+ _gcry_register_pk_dsa_progress (cb, cb_data);
+#endif
+#if USE_ELGAMAL
+ _gcry_register_pk_elg_progress (cb, cb_data);
+#endif
+ _gcry_register_primegen_progress (cb, cb_data);
+ _gcry_register_random_progress (cb, cb_data);
+}
diff --git a/grub-core/lib/libgcrypt/src/hmac256.c b/grub-core/lib/libgcrypt/src/hmac256.c
new file mode 100644
index 0000000..34def76
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/hmac256.c
@@ -0,0 +1,795 @@
+/* hmac256.c - Standalone HMAC implementation
+ * Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This is a standalone HMAC-SHA-256 implementation based on the code
+ from ../cipher/sha256.c. It is a second implementation to allow
+ comparing against the standard implementations and to be used for
+ internal consistency checks. It should not be used for sensitive
+ data because no mechanisms to clear the stack etc are used.
+
+ This module may be used standalone and requires only a few
+ standard definitions to be provided in a config.h file.
+
+ Types:
+
+ u32 - unsigned 32 bit type.
+
+ Constants:
+
+ WORDS_BIGENDIAN Defined to 1 on big endian systems.
+ inline If defined, it should yield the keyword used
+ to inline a function.
+ HAVE_U32_TYPEDEF Defined if the u32 type is available.
+ SIZEOF_UNSIGNED_INT Defined to the size in bytes of an unsigned int.
+ SIZEOF_UNSIGNED_LONG Defined to the size in bytes of an unsigned long.
+
+ STANDALONE Compile a test driver similar to the
+ sha1sum tool. This driver uses a self-test
+ identically to the one used by Libcgrypt
+ for testing this included module.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#if defined(__WIN32) && defined(STANDALONE)
+# include <fcntl.h> /* We need setmode(). */
+#endif
+
+/* For a native WindowsCE binary we need to include gpg-error.h to
+ provide a replacement for strerror. In other cases we need a
+ replacement macro for gpg_err_set_errno. */
+#ifdef __MINGW32CE__
+# include <gpg-error.h>
+#else
+# define gpg_err_set_errno(a) (errno = (a))
+#endif
+
+#include "hmac256.h"
+
+
+
+#ifndef HAVE_U32_TYPEDEF
+# undef u32 /* Undef a possible macro with that name. */
+# if SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int u32;
+# elif SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned long u32;
+# else
+# error no typedef for u32
+# endif
+# define HAVE_U32_TYPEDEF
+#endif
+
+
+
+
+/* The context used by this module. */
+struct hmac256_context
+{
+ u32 h0, h1, h2, h3, h4, h5, h6, h7;
+ u32 nblocks;
+ int count;
+ int finalized:1;
+ int use_hmac:1;
+ unsigned char buf[64];
+ unsigned char opad[64];
+};
+
+
+/* Rotate a 32 bit word. */
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+ror(u32 x, int n)
+{
+ __asm__("rorl %%cl,%0"
+ :"=r" (x)
+ :"0" (x),"c" (n));
+ return x;
+}
+#else
+#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
+#endif
+
+#define my_wipememory2(_ptr,_set,_len) do { \
+ volatile char *_vptr=(volatile char *)(_ptr); \
+ size_t _vlen=(_len); \
+ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+ } while(0)
+#define my_wipememory(_ptr,_len) my_wipememory2(_ptr,0,_len)
+
+
+
+
+/*
+ The SHA-256 core: Transform the message X which consists of 16
+ 32-bit-words. See FIPS 180-2 for details.
+ */
+static void
+transform (hmac256_context_t hd, const void *data_arg)
+{
+ const unsigned char *data = data_arg;
+
+#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
+#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
+#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
+#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
+ t2 = Sum0((a)) + Maj((a),(b),(c)); \
+ h = g; \
+ g = f; \
+ f = e; \
+ e = d + t1; \
+ d = c; \
+ c = b; \
+ b = a; \
+ a = t1 + t2; \
+ } while (0)
+
+ static const u32 K[64] =
+ {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ u32 a, b, c, d, e, f, g, h, t1, t2;
+ u32 x[16];
+ u32 w[64];
+ int i;
+
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+#ifdef WORDS_BIGENDIAN
+ memcpy (x, data, 64);
+#else /*!WORDS_BIGENDIAN*/
+ {
+ unsigned char *p2;
+
+ for (i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 )
+ {
+ p2[3] = *data++;
+ p2[2] = *data++;
+ p2[1] = *data++;
+ p2[0] = *data++;
+ }
+ }
+#endif /*!WORDS_BIGENDIAN*/
+
+ for (i=0; i < 16; i++)
+ w[i] = x[i];
+ for (; i < 64; i++)
+ w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
+
+ for (i=0; i < 64; i++)
+ R(a,b,c,d,e,f,g,h,K[i],w[i]);
+
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+}
+#undef Cho
+#undef Maj
+#undef Sum0
+#undef Sum1
+#undef S0
+#undef S1
+#undef R
+
+
+/* Finalize the current SHA256 calculation. */
+static void
+finalize (hmac256_context_t hd)
+{
+ u32 t, msb, lsb;
+ unsigned char *p;
+
+ if (hd->finalized)
+ return; /* Silently ignore a finalized context. */
+
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */
+
+ t = hd->nblocks;
+ /* Multiply by 64 to make a byte count. */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* Add the count. */
+ t = lsb;
+ if ((lsb += hd->count) < t)
+ msb++;
+ /* Multiply by 8 to make a bit count. */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->count < 56)
+ { /* Enough room. */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while (hd->count < 56)
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else
+ { /* Need one extra block. */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 64)
+ hd->buf[hd->count++] = 0;
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */;
+ memset (hd->buf, 0, 56 ); /* Zero out next next block. */
+ }
+ /* Append the 64 bit count. */
+ hd->buf[56] = msb >> 24;
+ hd->buf[57] = msb >> 16;
+ hd->buf[58] = msb >> 8;
+ hd->buf[59] = msb;
+ hd->buf[60] = lsb >> 24;
+ hd->buf[61] = lsb >> 16;
+ hd->buf[62] = lsb >> 8;
+ hd->buf[63] = lsb;
+ transform (hd, hd->buf);
+
+ /* Store the digest into hd->buf. */
+ p = hd->buf;
+#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
+ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+ X(5);
+ X(6);
+ X(7);
+#undef X
+ hd->finalized = 1;
+}
+
+
+
+/* Create a new context. On error NULL is returned and errno is set
+ appropriately. If KEY is given the function computes HMAC using
+ this key; with KEY given as NULL, a plain SHA-256 digest is
+ computed. */
+hmac256_context_t
+_gcry_hmac256_new (const void *key, size_t keylen)
+{
+ hmac256_context_t hd;
+
+ hd = malloc (sizeof *hd);
+ if (!hd)
+ return NULL;
+
+ hd->h0 = 0x6a09e667;
+ hd->h1 = 0xbb67ae85;
+ hd->h2 = 0x3c6ef372;
+ hd->h3 = 0xa54ff53a;
+ hd->h4 = 0x510e527f;
+ hd->h5 = 0x9b05688c;
+ hd->h6 = 0x1f83d9ab;
+ hd->h7 = 0x5be0cd19;
+ hd->nblocks = 0;
+ hd->count = 0;
+ hd->finalized = 0;
+ hd->use_hmac = 0;
+
+ if (key)
+ {
+ int i;
+ unsigned char ipad[64];
+
+ memset (ipad, 0, 64);
+ memset (hd->opad, 0, 64);
+ if (keylen <= 64)
+ {
+ memcpy (ipad, key, keylen);
+ memcpy (hd->opad, key, keylen);
+ }
+ else
+ {
+ hmac256_context_t tmphd;
+
+ tmphd = _gcry_hmac256_new (NULL, 0);
+ if (!tmphd)
+ {
+ free (hd);
+ return NULL;
+ }
+ _gcry_hmac256_update (tmphd, key, keylen);
+ finalize (tmphd);
+ memcpy (ipad, tmphd->buf, 32);
+ memcpy (hd->opad, tmphd->buf, 32);
+ _gcry_hmac256_release (tmphd);
+ }
+ for (i=0; i < 64; i++)
+ {
+ ipad[i] ^= 0x36;
+ hd->opad[i] ^= 0x5c;
+ }
+ hd->use_hmac = 1;
+ _gcry_hmac256_update (hd, ipad, 64);
+ my_wipememory (ipad, 64);
+ }
+
+ return hd;
+}
+
+/* Release a context created by _gcry_hmac256_new. CTX may be NULL
+ in which case the function does nothing. */
+void
+_gcry_hmac256_release (hmac256_context_t ctx)
+{
+ if (ctx)
+ {
+ /* Note: We need to take care not to modify errno. */
+ if (ctx->use_hmac)
+ my_wipememory (ctx->opad, 64);
+ free (ctx);
+ }
+}
+
+
+/* Update the message digest with the contents of BUFFER containing
+ LENGTH bytes. */
+void
+_gcry_hmac256_update (hmac256_context_t hd,
+ const void *buffer, size_t length)
+{
+ const unsigned char *inbuf = buffer;
+
+ if (hd->finalized)
+ return; /* Silently ignore a finalized context. */
+
+ if (hd->count == 64)
+ {
+ /* Flush the buffer. */
+ transform (hd, hd->buf);
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf)
+ return; /* Only flushing was requested. */
+ if (hd->count)
+ {
+ for (; length && hd->count < 64; length--)
+ hd->buf[hd->count++] = *inbuf++;
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */
+ if (!length)
+ return;
+ }
+
+
+ while (length >= 64)
+ {
+ transform (hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ length -= 64;
+ inbuf += 64;
+ }
+ for (; length && hd->count < 64; length--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/* Finalize an operation and return the digest. If R_DLEN is not NULL
+ the length of the digest will be stored at that address. The
+ returned value is valid as long as the context exists. On error
+ NULL is returned. */
+const void *
+_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen)
+{
+ finalize (hd);
+ if (hd->use_hmac)
+ {
+ hmac256_context_t tmphd;
+
+ tmphd = _gcry_hmac256_new (NULL, 0);
+ if (!tmphd)
+ {
+ free (hd);
+ return NULL;
+ }
+ _gcry_hmac256_update (tmphd, hd->opad, 64);
+ _gcry_hmac256_update (tmphd, hd->buf, 32);
+ finalize (tmphd);
+ memcpy (hd->buf, tmphd->buf, 32);
+ _gcry_hmac256_release (tmphd);
+ }
+ if (r_dlen)
+ *r_dlen = 32;
+ return (void*)hd->buf;
+}
+
+
+/* Convenience function to compute the HMAC-SHA256 of one file. The
+ user needs to provide a buffer RESULT of at least 32 bytes, he
+ needs to put the size of the buffer into RESULTSIZE and the
+ FILENAME. KEY and KEYLEN are as described for _gcry_hmac256_new.
+ On success the function returns the valid length of the result
+ buffer (which will be 32) or -1 on error. On error ERRNO is set
+ appropriate. */
+int
+_gcry_hmac256_file (void *result, size_t resultsize, const char *filename,
+ const void *key, size_t keylen)
+{
+ FILE *fp;
+ hmac256_context_t hd;
+ size_t buffer_size, nread, digestlen;
+ char *buffer;
+ const unsigned char *digest;
+
+ fp = fopen (filename, "rb");
+ if (!fp)
+ return -1;
+
+ hd = _gcry_hmac256_new (key, keylen);
+ if (!hd)
+ {
+ fclose (fp);
+ return -1;
+ }
+
+ buffer_size = 32768;
+ buffer = malloc (buffer_size);
+ if (!buffer)
+ {
+ fclose (fp);
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ while ( (nread = fread (buffer, 1, buffer_size, fp)))
+ _gcry_hmac256_update (hd, buffer, nread);
+
+ free (buffer);
+
+ if (ferror (fp))
+ {
+ fclose (fp);
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ fclose (fp);
+
+ digest = _gcry_hmac256_finalize (hd, &digestlen);
+ if (!digest)
+ {
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ if (digestlen > resultsize)
+ {
+ _gcry_hmac256_release (hd);
+ gpg_err_set_errno (EINVAL);
+ return -1;
+ }
+ memcpy (result, digest, digestlen);
+ _gcry_hmac256_release (hd);
+
+ return digestlen;
+}
+
+
+
+#ifdef STANDALONE
+static int
+selftest (void)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const unsigned char expect[32];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+ 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+ 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+ 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
+ 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
+ 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
+ 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
+ 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
+ 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
+ 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
+ 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
+ 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
+ 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
+
+ { "data-54 key-131",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
+ 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
+ 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
+ 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
+
+ { "data-152 key-131",
+ "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
+ 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
+ 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
+ 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
+
+ { NULL }
+ };
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ hmac256_context_t hmachd;
+ const unsigned char *digest;
+ size_t dlen;
+
+ hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
+ if (!hmachd)
+ return -1;
+ _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
+ digest = _gcry_hmac256_finalize (hmachd, &dlen);
+ if (!digest)
+ {
+ _gcry_hmac256_release (hmachd);
+ return -1;
+ }
+ if (dlen != sizeof (tv[tvidx].expect)
+ || memcmp (digest, tv[tvidx].expect, sizeof (tv[tvidx].expect)))
+ {
+ _gcry_hmac256_release (hmachd);
+ return -1;
+ }
+ _gcry_hmac256_release (hmachd);
+ }
+
+ return 0; /* Succeeded. */
+}
+
+
+int
+main (int argc, char **argv)
+{
+ const char *pgm;
+ int last_argc = -1;
+ const char *key;
+ size_t keylen;
+ FILE *fp;
+ hmac256_context_t hd;
+ const unsigned char *digest;
+ char buffer[4096];
+ size_t n, dlen, idx;
+ int use_stdin = 0;
+ int use_binary = 0;
+
+ assert (sizeof (u32) == 4);
+#ifdef __WIN32
+ setmode (fileno (stdin), O_BINARY);
+#endif
+
+ if (argc)
+ {
+ pgm = strrchr (*argv, '/');
+ if (pgm)
+ pgm++;
+ else
+ pgm = *argv;
+ argc--; argv++;
+ }
+ else
+ pgm = "?";
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ {
+ fputs ("hmac256 (Libgcrypt) " VERSION "\n"
+ "Copyright (C) 2008 Free Software Foundation, Inc.\n"
+ "License LGPLv2.1+: GNU LGPL version 2.1 or later "
+ "<http://gnu.org/licenses/old-licenses/lgpl-2.1.html>\n"
+ "This is free software: you are free to change and "
+ "redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--binary"))
+ {
+ argc--; argv++;
+ use_binary = 1;
+ }
+ }
+
+ if (argc < 1)
+ {
+ fprintf (stderr, "usage: %s [--binary] key [filename]\n", pgm);
+ exit (1);
+ }
+
+#ifdef __WIN32
+ if (use_binary)
+ setmode (fileno (stdout), O_BINARY);
+#endif
+
+ key = *argv;
+ argc--, argv++;
+ keylen = strlen (key);
+ use_stdin = !argc;
+
+ if (selftest ())
+ {
+ fprintf (stderr, "%s: fatal error: self-test failed\n", pgm);
+ exit (2);
+ }
+
+ for (; argc || use_stdin; argv++, argc--)
+ {
+ const char *fname = use_stdin? "-" : *argv;
+ fp = use_stdin? stdin : fopen (fname, "rb");
+ if (!fp)
+ {
+ fprintf (stderr, "%s: can't open `%s': %s\n",
+ pgm, fname, strerror (errno));
+ exit (1);
+ }
+ hd = _gcry_hmac256_new (key, keylen);
+ if (!hd)
+ {
+ fprintf (stderr, "%s: can't allocate context: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ while ( (n = fread (buffer, 1, sizeof buffer, fp)))
+ _gcry_hmac256_update (hd, buffer, n);
+ if (ferror (fp))
+ {
+ fprintf (stderr, "%s: error reading `%s': %s\n",
+ pgm, fname, strerror (errno));
+ exit (1);
+ }
+ if (!use_stdin)
+ fclose (fp);
+
+ digest = _gcry_hmac256_finalize (hd, &dlen);
+ if (!digest)
+ {
+ fprintf (stderr, "%s: error computing HMAC: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ if (use_binary)
+ {
+ if (fwrite (digest, dlen, 1, stdout) != 1)
+ {
+ fprintf (stderr, "%s: error writing output: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ if (use_stdin)
+ break;
+ }
+ else
+ {
+ for (idx=0; idx < dlen; idx++)
+ printf ("%02x", digest[idx]);
+ _gcry_hmac256_release (hd);
+ if (use_stdin)
+ {
+ putchar ('\n');
+ break;
+ }
+ printf (" %s\n", fname);
+ }
+ }
+
+ return 0;
+}
+#endif /*STANDALONE*/
+
+
+/*
+Local Variables:
+compile-command: "cc -Wall -g -I.. -DSTANDALONE -o hmac256 hmac256.c"
+End:
+*/
diff --git a/grub-core/lib/libgcrypt/src/hmac256.h b/grub-core/lib/libgcrypt/src/hmac256.h
new file mode 100644
index 0000000..df28e72
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/hmac256.h
@@ -0,0 +1,36 @@
+/* hmac256.h - Declarations for _gcry_hmac256
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HMAC256_H
+#define HMAC256_H
+
+
+struct hmac256_context;
+typedef struct hmac256_context *hmac256_context_t;
+
+hmac256_context_t _gcry_hmac256_new (const void *key, size_t keylen);
+void _gcry_hmac256_update (hmac256_context_t hd, const void *buf, size_t len);
+const void *_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen);
+void _gcry_hmac256_release (hmac256_context_t hd);
+
+int _gcry_hmac256_file (void *result, size_t resultsize, const char *filename,
+ const void *key, size_t keylen);
+
+
+#endif /*HMAC256_H*/
diff --git a/grub-core/lib/libgcrypt/src/hwfeatures.c b/grub-core/lib/libgcrypt/src/hwfeatures.c
new file mode 100644
index 0000000..c356798
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/hwfeatures.c
@@ -0,0 +1,192 @@
+/* hwfeatures.c - Detect hardware features.
+ * Copyright (C) 2007, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+
+/* A bit vector describing the hardware features currently
+ available. */
+static unsigned int hw_features;
+
+
+/* Return a bit vector describing the available hardware features.
+ The HWF_ constants are used to test for them. */
+unsigned int
+_gcry_get_hw_features (void)
+{
+ return hw_features;
+}
+
+
+#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+static void
+detect_ia32_gnuc (void)
+{
+ /* The code here is only useful for the PadLock engine thus we don't
+ build it if that support has been disabled. */
+ int has_cpuid = 0;
+ char vendor_id[12+1];
+
+ /* Detect the CPUID feature by testing some undefined behaviour (16
+ vs 32 bit pushf/popf). */
+ asm volatile
+ ("pushf\n\t" /* Copy flags to EAX. */
+ "popl %%eax\n\t"
+ "movl %%eax, %%ecx\n\t" /* Save flags into ECX. */
+ "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags. */
+ "pushl %%eax\n\t"
+ "popf\n\t"
+ "pushf\n\t" /* Copy changed flags again to EAX. */
+ "popl %%eax\n\t"
+ "pushl %%ecx\n\t" /* Restore flags from ECX. */
+ "popf\n\t"
+ "xorl %%eax, %%ecx\n\t" /* Compare flags against saved flags. */
+ "jz .Lno_cpuid%=\n\t" /* Toggling did not work, thus no CPUID. */
+ "movl $1, %0\n" /* Worked. true -> HAS_CPUID. */
+ ".Lno_cpuid%=:\n\t"
+ : "+r" (has_cpuid)
+ :
+ : "%eax", "%ecx", "cc"
+ );
+
+ if (!has_cpuid)
+ return; /* No way. */
+
+ asm volatile
+ ("pushl %%ebx\n\t" /* Save GOT register. */
+ "xorl %%eax, %%eax\n\t" /* 0 -> EAX. */
+ "cpuid\n\t" /* Get vendor ID. */
+ "movl %%ebx, (%0)\n\t" /* EBX,EDX,ECX -> VENDOR_ID. */
+ "movl %%edx, 4(%0)\n\t"
+ "movl %%ecx, 8(%0)\n\t"
+ "popl %%ebx\n"
+ :
+ : "S" (&vendor_id[0])
+ : "%eax", "%ecx", "%edx", "cc"
+ );
+ vendor_id[12] = 0;
+
+ if (0)
+ ; /* Just to make "else if" and ifdef macros look pretty. */
+#ifdef ENABLE_PADLOCK_SUPPORT
+ else if (!strcmp (vendor_id, "CentaurHauls"))
+ {
+ /* This is a VIA CPU. Check what PadLock features we have. */
+ asm volatile
+ ("pushl %%ebx\n\t" /* Save GOT register. */
+ "movl $0xC0000000, %%eax\n\t" /* Check for extended centaur */
+ "cpuid\n\t" /* feature flags. */
+ "popl %%ebx\n\t" /* Restore GOT register. */
+ "cmpl $0xC0000001, %%eax\n\t"
+ "jb .Lready%=\n\t" /* EAX < 0xC0000000 => no padlock. */
+
+ "pushl %%ebx\n\t" /* Save GOT register. */
+ "movl $0xC0000001, %%eax\n\t" /* Ask for the extended */
+ "cpuid\n\t" /* feature flags. */
+ "popl %%ebx\n\t" /* Restore GOT register. */
+
+ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
+ "andl $0x0C, %%eax\n\t" /* Test bits 2 and 3 to see whether */
+ "cmpl $0x0C, %%eax\n\t" /* the RNG exists and is enabled. */
+ "jnz .Lno_rng%=\n\t"
+ "orl $1, %0\n" /* Set our HWF_PADLOCK_RNG bit. */
+
+ ".Lno_rng%=:\n\t"
+ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
+ "andl $0xC0, %%eax\n\t" /* Test bits 6 and 7 to see whether */
+ "cmpl $0xC0, %%eax\n\t" /* the ACE exists and is enabled. */
+ "jnz .Lno_ace%=\n\t"
+ "orl $2, %0\n" /* Set our HWF_PADLOCK_AES bit. */
+
+ ".Lno_ace%=:\n\t"
+ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
+ "andl $0xC00, %%eax\n\t" /* Test bits 10, 11 to see whether */
+ "cmpl $0xC00, %%eax\n\t" /* the PHE exists and is enabled. */
+ "jnz .Lno_phe%=\n\t"
+ "orl $4, %0\n" /* Set our HWF_PADLOCK_SHA bit. */
+
+ ".Lno_phe%=:\n\t"
+ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
+ "andl $0x3000, %%eax\n\t" /* Test bits 12, 13 to see whether */
+ "cmpl $0x3000, %%eax\n\t" /* MONTMUL exists and is enabled. */
+ "jnz .Lready%=\n\t"
+ "orl $8, %0\n" /* Set our HWF_PADLOCK_MMUL bit. */
+
+ ".Lready%=:\n"
+ : "+r" (hw_features)
+ :
+ : "%eax", "%edx", "cc"
+ );
+ }
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+ else if (!strcmp (vendor_id, "GenuineIntel"))
+ {
+ /* This is an Intel CPU. */
+ asm volatile
+ ("pushl %%ebx\n\t" /* Save GOT register. */
+ "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */
+ "cpuid\n"
+ "popl %%ebx\n\t" /* Restore GOT register. */
+ "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */
+ "jz .Lno_aes%=\n\t" /* No AES support. */
+ "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */
+
+ ".Lno_aes%=:\n"
+ : "+r" (hw_features)
+ :
+ : "%eax", "%ecx", "%edx", "cc"
+ );
+ }
+ else if (!strcmp (vendor_id, "AuthenticAMD"))
+ {
+ /* This is an AMD CPU. */
+
+ }
+}
+#endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */
+
+
+/* Detect the available hardware features. This function is called
+ once right at startup and we assume that no other threads are
+ running. */
+void
+_gcry_detect_hw_features (unsigned int disabled_features)
+{
+ hw_features = 0;
+
+ if (fips_mode ())
+ return; /* Hardware support is not to be evaluated. */
+
+#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4
+#ifdef __GNUC__
+ detect_ia32_gnuc ();
+#endif
+#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 8
+#ifdef __GNUC__
+#endif
+#endif
+
+ hw_features &= ~disabled_features;
+}
diff --git a/grub-core/lib/libgcrypt/src/libgcrypt-config.in b/grub-core/lib/libgcrypt/src/libgcrypt-config.in
new file mode 100644
index 0000000..c052638
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/libgcrypt-config.in
@@ -0,0 +1,189 @@
+#!/bin/sh
+# Copyright (C) 1999, 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# File: @configure_input@
+
+# General.
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+version="@VERSION@"
+includedir="@includedir@"
+libdir="@libdir@"
+gpg_error_libs="@GPG_ERROR_LIBS@"
+gpg_error_cflags="@GPG_ERROR_CFLAGS@"
+
+# libgcrypt values.
+libs="@LIBGCRYPT_CONFIG_LIBS@"
+cflags="@LIBGCRYPT_CONFIG_CFLAGS@"
+
+# API info
+api_version="@LIBGCRYPT_CONFIG_API_VERSION@"
+
+# Configured for host
+my_host="@LIBGCRYPT_CONFIG_HOST@"
+
+# Misc information.
+symmetric_ciphers="@LIBGCRYPT_CIPHERS@"
+asymmetric_ciphers="@LIBGCRYPT_PUBKEY_CIPHERS@"
+digests="@LIBGCRYPT_DIGESTS@"
+
+# State variables.
+echo_libs=no
+echo_cflags=no
+echo_prefix=no
+echo_algorithms=no
+echo_exec_prefix=no
+echo_version=no
+echo_api_version=no
+echo_host=no
+
+# Prints usage information.
+usage()
+{
+ cat <<EOF
+Usage: $0 [OPTIONS]
+Options:
+ [--prefix]
+ [--exec-prefix]
+ [--version]
+ [--api-version]
+ [--libs]
+ [--cflags]
+ [--algorithms]
+ [--host]
+EOF
+ exit $1
+}
+
+if test $# -eq 0; then
+ # Nothing to do.
+ usage 1 1>&2
+fi
+
+while test $# -gt 0; do
+ case "$1" in
+ # Set up `optarg'.
+ --*=*)
+ optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
+ ;;
+ *)
+ optarg=""
+ ;;
+ esac
+
+ case $1 in
+ --thread=*)
+ echo "$0: --thread option obsolete: use the thread callback interface" 1>&2
+ exit 1
+ ;;
+ --prefix=*)
+ # For compatibility reasons with old M4 macros, we ignore
+ # setting of prefix.
+ ;;
+ --prefix)
+ echo_prefix=yes
+ ;;
+ --exec-prefix=*)
+ ;;
+ --exec-prefix)
+ echo_exec_prefix=yes
+ ;;
+ --version)
+ echo_version=yes
+ ;;
+ --api-version)
+ echo_api_version=yes
+ ;;
+ --cflags)
+ echo_cflags=yes
+ ;;
+ --libs)
+ echo_libs=yes
+ ;;
+ --algorithms)
+ echo_algorithms=yes
+ ;;
+ --host)
+ echo_host=yes
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+
+if test "$echo_prefix" = "yes"; then
+ echo "$prefix"
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+ echo "$exec_prefix"
+fi
+
+if test "$echo_cflags" = "yes"; then
+ includes=""
+ cflags_final="$cflags"
+
+ # Set up `includes'.
+ if test "x$includedir" != "x/usr/include" -a "x$includedir" != "x/include"; then
+ includes="-I$includedir"
+ fi
+ # Set up `cflags_final'.
+ cflags_final="$cflags_final $gpg_error_cflags"
+
+ tmp=""
+ for i in $includes $cflags_final; do
+ if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then
+ tmp="$tmp $i"
+ fi
+ done
+ echo $tmp
+fi
+
+if test "$echo_libs" = "yes"; then
+ libdirs=""
+ libs_final="$libs"
+
+ # Set up `libdirs'.
+ if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then
+ libdirs="-L$libdir"
+ fi
+
+ # Set up `libs_final'.
+ libs_final="$libs_final $gpg_error_libs"
+
+ tmp=""
+ for i in $libdirs $libs_final; do
+ if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then
+ tmp="$tmp $i"
+ fi
+ done
+ echo $tmp
+fi
+
+if test "$echo_version" = "yes"; then
+ echo "$version"
+fi
+
+if test "$echo_api_version" = "yes"; then
+ echo "$api_version"
+fi
+
+if test "$echo_host" = "yes"; then
+ echo "$my_host"
+fi
+
+if test "$echo_algorithms" = "yes"; then
+ echo "Symmetric cipher algorithms: $symmetric_ciphers"
+ echo "Public-key cipher algorithms: $asymmetric_ciphers"
+ echo "Message digest algorithms: $digests"
+fi
diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.def b/grub-core/lib/libgcrypt/src/libgcrypt.def
new file mode 100644
index 0000000..9bf0167
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/libgcrypt.def
@@ -0,0 +1,213 @@
+;; libgcrypt.defs - Exported symbols for W32
+;; Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+;;
+;; This file is part of Libgcrypt.
+;;
+;; Libgcrypt is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU Lesser General Public License as
+;; published by the Free Software Foundation; either version 2.1 of
+;; the License, or (at your option) any later version.
+;;
+;; Libgcrypt is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+;;
+
+;; Note: This file should be updated manually and the ordinals shall
+;; never be changed. Also check libgcrypt.vers and visibility.h.
+
+
+EXPORTS
+ gcry_check_version @1
+ gcry_control @2
+
+ gcry_malloc @3
+ gcry_calloc @4
+ gcry_malloc_secure @5
+ gcry_calloc_secure @6
+ gcry_realloc @7
+ gcry_strdup @8
+ gcry_xmalloc @9
+ gcry_xcalloc @10
+ gcry_xmalloc_secure @11
+ gcry_xcalloc_secure @12
+ gcry_xrealloc @13
+ gcry_xstrdup @14
+ gcry_is_secure @15
+ gcry_free @16
+
+ gcry_set_progress_handler @17
+ gcry_set_allocation_handler @18
+ gcry_set_outofcore_handler @19
+ gcry_set_fatalerror_handler @20
+ gcry_set_log_handler @21
+ gcry_set_gettext_handler @22
+
+ gcry_strerror @23
+ gcry_strsource @24
+ gcry_err_code_from_errno @25
+ gcry_err_code_to_errno @26
+ gcry_err_make_from_errno @27
+ gcry_error_from_errno @28
+
+ gcry_sexp_new @29
+ gcry_sexp_create @30
+ gcry_sexp_sscan @31
+ gcry_sexp_build @32
+ gcry_sexp_build_array @33
+ gcry_sexp_release @34
+ gcry_sexp_canon_len @35
+ gcry_sexp_sprint @36
+ gcry_sexp_dump @37
+ gcry_sexp_cons @38
+ gcry_sexp_alist @39
+ gcry_sexp_vlist @40
+ gcry_sexp_append @41
+ gcry_sexp_prepend @42
+ gcry_sexp_find_token @43
+ gcry_sexp_length @44
+ gcry_sexp_nth @45
+ gcry_sexp_car @46
+ gcry_sexp_cdr @47
+ gcry_sexp_cadr @48
+ gcry_sexp_nth_data @49
+ gcry_sexp_nth_mpi @50
+
+ gcry_mpi_new @51
+ gcry_mpi_snew @52
+ gcry_mpi_release @53
+ gcry_mpi_copy @54
+ gcry_mpi_set @55
+ gcry_mpi_set_ui @56
+ gcry_mpi_swap @57
+ gcry_mpi_cmp @58
+ gcry_mpi_cmp_ui @59
+ gcry_mpi_scan @60
+ gcry_mpi_print @61
+ gcry_mpi_aprint @62
+ gcry_mpi_dump @63
+ gcry_mpi_add @64
+ gcry_mpi_add_ui @65
+ gcry_mpi_addm @66
+ gcry_mpi_sub @67
+ gcry_mpi_sub_ui @68
+ gcry_mpi_subm @69
+ gcry_mpi_mul @70
+ gcry_mpi_mul_ui @71
+ gcry_mpi_mulm @72
+ gcry_mpi_mul_2exp @73
+ gcry_mpi_div @74
+ gcry_mpi_mod @75
+ gcry_mpi_powm @76
+ gcry_mpi_gcd @77
+ gcry_mpi_invm @78
+ gcry_mpi_get_nbits @79
+ gcry_mpi_test_bit @80
+ gcry_mpi_set_bit @81
+ gcry_mpi_clear_bit @82
+ gcry_mpi_set_highbit @83
+ gcry_mpi_clear_highbit @84
+ gcry_mpi_rshift @85
+ gcry_mpi_set_opaque @86
+ gcry_mpi_get_opaque @87
+ gcry_mpi_set_flag @88
+ gcry_mpi_clear_flag @89
+ gcry_mpi_get_flag @90
+
+
+ gcry_cipher_open @92
+ gcry_cipher_close @93
+ gcry_cipher_ctl @94
+ gcry_cipher_info @95
+ gcry_cipher_algo_info @96
+ gcry_cipher_algo_name @97
+ gcry_cipher_map_name @98
+ gcry_cipher_mode_from_oid @99
+ gcry_cipher_encrypt @100
+ gcry_cipher_decrypt @101
+ gcry_cipher_get_algo_keylen @102
+ gcry_cipher_get_algo_blklen @103
+
+;; @104 used to be part of the module register interface
+
+ gcry_pk_encrypt @105
+ gcry_pk_decrypt @106
+ gcry_pk_sign @107
+ gcry_pk_verify @108
+ gcry_pk_testkey @109
+ gcry_pk_genkey @110
+ gcry_pk_ctl @111
+ gcry_pk_algo_info @112
+ gcry_pk_algo_name @113
+ gcry_pk_map_name @114
+ gcry_pk_get_nbits @115
+ gcry_pk_get_keygrip @116
+
+;; @117 used to be part of the module register interface
+
+;;
+;; 118 to 142 were used in previous Libgcrypt versions for the gcry_ac
+;; interface
+;;
+
+ gcry_md_open @143
+ gcry_md_close @144
+ gcry_md_enable @145
+ gcry_md_copy @146
+ gcry_md_reset @147
+ gcry_md_ctl @148
+ gcry_md_write @149
+ gcry_md_read @150
+ gcry_md_hash_buffer @151
+ gcry_md_get_algo @152
+ gcry_md_get_algo_dlen @153
+ gcry_md_is_enabled @154
+ gcry_md_is_secure @155
+ gcry_md_info @156
+ gcry_md_algo_info @157
+ gcry_md_algo_name @158
+ gcry_md_map_name @159
+ gcry_md_setkey @160
+;; @161 used to be part of the module register interface
+ gcry_randomize @162
+ gcry_random_add_bytes @163
+ gcry_random_bytes @164
+ gcry_random_bytes_secure @165
+ gcry_mpi_randomize @166
+
+ gcry_prime_generate @167
+ gcry_prime_group_generator @168
+ gcry_prime_release_factors @169
+ gcry_prime_check @170
+
+ gcry_create_nonce @171
+
+ gcry_md_debug @172
+
+;; @173 used to be part of the module register interface
+;; @174 used to be part of the module register interface
+;; @175 used to be part of the module register interface
+;; @176 used to be part of the module register interface
+;; @177 used to be part of the module register interface
+;; @178 used to be part of the module register interface
+;;
+;; @179 to @186 used to be part of the removed gcry_ac interface
+;;
+
+ gcry_sexp_nth_string @187
+
+ gcry_cipher_setkey @188
+ gcry_cipher_setiv @189
+ gcry_cipher_setctr @190
+
+ gcry_mpi_lshift @191
+
+ gcry_pk_get_curve @192
+ gcry_pk_get_param @193
+
+ gcry_kdf_derive @194
diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.m4 b/grub-core/lib/libgcrypt/src/libgcrypt.m4
new file mode 100644
index 0000000..6cf482f
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/libgcrypt.m4
@@ -0,0 +1,122 @@
+dnl Autoconf macros for libgcrypt
+dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; as a special exception the author gives
+dnl unlimited permission to copy and/or distribute it, with or without
+dnl modifications, as long as this notice is preserved.
+dnl
+dnl This file is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
+dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
+dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
+dnl with the API version to also check the API compatibility. Example:
+dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed
+dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
+dnl this features allows to prevent build against newer versions of libgcrypt
+dnl with a changed API.
+dnl
+AC_DEFUN([AM_PATH_LIBGCRYPT],
+[ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_ARG_WITH(libgcrypt-prefix,
+ AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
+ [prefix where LIBGCRYPT is installed (optional)]),
+ libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
+ if test x$libgcrypt_config_prefix != x ; then
+ if test x${LIBGCRYPT_CONFIG+set} != xset ; then
+ LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config
+ fi
+ fi
+
+ AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no)
+ tmp=ifelse([$1], ,1:1.2.0,$1)
+ if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+ req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
+ min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+ else
+ req_libgcrypt_api=0
+ min_libgcrypt_version="$tmp"
+ fi
+
+ AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
+ ok=no
+ if test "$LIBGCRYPT_CONFIG" != "no" ; then
+ req_major=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+ req_minor=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+ req_micro=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
+ major=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+ minor=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+ micro=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
+ if test "$major" -gt "$req_major"; then
+ ok=yes
+ else
+ if test "$major" -eq "$req_major"; then
+ if test "$minor" -gt "$req_minor"; then
+ ok=yes
+ else
+ if test "$minor" -eq "$req_minor"; then
+ if test "$micro" -ge "$req_micro"; then
+ ok=yes
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ AC_MSG_RESULT([yes ($libgcrypt_config_version)])
+ else
+ AC_MSG_RESULT(no)
+ fi
+ if test $ok = yes; then
+ # If we have a recent libgcrypt, we should also check that the
+ # API is compatible
+ if test "$req_libgcrypt_api" -gt 0 ; then
+ tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
+ if test "$tmp" -gt 0 ; then
+ AC_MSG_CHECKING([LIBGCRYPT API version])
+ if test "$req_libgcrypt_api" -eq "$tmp" ; then
+ AC_MSG_RESULT([okay])
+ else
+ ok=no
+ AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
+ LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
+ ifelse([$2], , :, [$2])
+ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+ if test x"$libgcrypt_config_host" != xnone ; then
+ if test x"$libgcrypt_config_host" != x"$host" ; then
+ AC_MSG_WARN([[
+***
+*** The config script $LIBGCRYPT_CONFIG was
+*** built for $libgcrypt_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-libgcrypt-prefix
+*** to specify a matching config script.
+***]])
+ fi
+ fi
+ else
+ LIBGCRYPT_CFLAGS=""
+ LIBGCRYPT_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(LIBGCRYPT_CFLAGS)
+ AC_SUBST(LIBGCRYPT_LIBS)
+])
diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.vers b/grub-core/lib/libgcrypt/src/libgcrypt.vers
new file mode 100644
index 0000000..dcb3749
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/libgcrypt.vers
@@ -0,0 +1,94 @@
+# libgcrypt.vers - What symbols to export -*- std -*-
+# Copyright (C) 2002, 2004, 2008, 2011 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# NOTE: When adding new functions, please make sure to add them to
+# visibility.h and libgcrypt.def as well.
+
+GCRYPT_1.6 {
+ global:
+ gcry_check_version; gcry_control;
+ gcry_set_allocation_handler; gcry_set_fatalerror_handler;
+ gcry_set_gettext_handler; gcry_set_log_handler;
+ gcry_set_outofcore_handler; gcry_set_progress_handler;
+
+ gcry_err_code_from_errno; gcry_err_code_to_errno;
+ gcry_err_make_from_errno; gcry_error_from_errno;
+ gcry_strerror; gcry_strsource;
+
+ gcry_free; gcry_malloc; gcry_malloc_secure; gcry_calloc;
+ gcry_calloc_secure; gcry_realloc; gcry_strdup; gcry_is_secure;
+ gcry_xcalloc; gcry_xcalloc_secure; gcry_xmalloc;
+ gcry_xmalloc_secure; gcry_xrealloc; gcry_xstrdup;
+
+ gcry_md_algo_info; gcry_md_algo_name; gcry_md_close;
+ gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get;
+ gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer;
+ gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure;
+ gcry_md_map_name; gcry_md_open; gcry_md_read;
+ gcry_md_reset; gcry_md_setkey;
+ gcry_md_write; gcry_md_debug;
+
+ gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close;
+ gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt;
+ gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen;
+ gcry_cipher_info; gcry_cipher_map_name;
+ gcry_cipher_mode_from_oid; gcry_cipher_open;
+ gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr;
+
+ gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl;
+ gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey;
+ gcry_pk_get_keygrip; gcry_pk_get_nbits;
+ gcry_pk_map_name; gcry_pk_register; gcry_pk_sign;
+ gcry_pk_testkey; gcry_pk_verify;
+ gcry_pk_get_curve; gcry_pk_get_param;
+
+ gcry_kdf_derive;
+
+ gcry_prime_check; gcry_prime_generate;
+ gcry_prime_group_generator; gcry_prime_release_factors;
+
+ gcry_random_add_bytes; gcry_random_bytes; gcry_random_bytes_secure;
+ gcry_randomize; gcry_create_nonce;
+
+ gcry_sexp_alist; gcry_sexp_append; gcry_sexp_build;
+ gcry_sexp_build_array; gcry_sexp_cadr; gcry_sexp_canon_len;
+ gcry_sexp_car; gcry_sexp_cdr; gcry_sexp_cons; gcry_sexp_create;
+ gcry_sexp_dump; gcry_sexp_find_token; gcry_sexp_length;
+ gcry_sexp_new; gcry_sexp_nth; gcry_sexp_nth_data;
+ gcry_sexp_nth_mpi; gcry_sexp_prepend; gcry_sexp_release;
+ gcry_sexp_sprint; gcry_sexp_sscan; gcry_sexp_vlist;
+ gcry_sexp_nth_string;
+
+ gcry_mpi_add; gcry_mpi_add_ui; gcry_mpi_addm; gcry_mpi_aprint;
+ gcry_mpi_clear_bit; gcry_mpi_clear_flag; gcry_mpi_clear_highbit;
+ gcry_mpi_cmp; gcry_mpi_cmp_ui; gcry_mpi_copy; gcry_mpi_div;
+ gcry_mpi_dump; gcry_mpi_gcd; gcry_mpi_get_flag; gcry_mpi_get_nbits;
+ gcry_mpi_get_opaque; gcry_mpi_invm; gcry_mpi_mod; gcry_mpi_mul;
+ gcry_mpi_mul_2exp; gcry_mpi_mul_ui; gcry_mpi_mulm; gcry_mpi_new;
+ gcry_mpi_powm; gcry_mpi_print; gcry_mpi_randomize; gcry_mpi_release;
+ gcry_mpi_rshift; gcry_mpi_scan; gcry_mpi_set; gcry_mpi_set_bit;
+ gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque;
+ gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui;
+ gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit;
+ gcry_mpi_lshift;
+
+ local:
+ *;
+
+};
diff --git a/grub-core/lib/libgcrypt/src/misc.c b/grub-core/lib/libgcrypt/src/misc.c
new file mode 100644
index 0000000..17bd546
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/misc.c
@@ -0,0 +1,298 @@
+/* misc.c
+ * Copyright (C) 1999, 2001, 2002, 2003, 2007,
+ * 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "secmem.h"
+
+static int verbosity_level = 0;
+
+static void (*fatal_error_handler)(void*,int, const char*) = NULL;
+static void *fatal_error_handler_value = 0;
+static void (*log_handler)(void*,int, const char*, va_list) = NULL;
+static void *log_handler_value = 0;
+
+static const char *(*user_gettext_handler)( const char * ) = NULL;
+
+void
+gcry_set_gettext_handler( const char *(*f)(const char*) )
+{
+ user_gettext_handler = f;
+}
+
+
+const char *
+_gcry_gettext( const char *key )
+{
+ if( user_gettext_handler )
+ return user_gettext_handler( key );
+ /* FIXME: switch the domain to gnupg and restore later */
+ return key;
+}
+
+void
+gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value)
+{
+ fatal_error_handler_value = value;
+ fatal_error_handler = fnc;
+}
+
+static void
+write2stderr( const char *s )
+{
+ /* Dummy variable to silence gcc warning. */
+ int res = write( 2, s, strlen(s) );
+ (void) res;
+}
+
+/*
+ * This function is called for fatal errors. A caller might want to
+ * set his own handler because this function simply calls abort().
+ */
+void
+_gcry_fatal_error (int rc, const char *text)
+{
+ if ( !text ) /* get a default text */
+ text = gpg_strerror (rc);
+
+ if (fatal_error_handler && !fips_mode () )
+ fatal_error_handler (fatal_error_handler_value, rc, text);
+
+ fips_signal_fatal_error (text);
+ write2stderr("\nFatal error: ");
+ write2stderr(text);
+ write2stderr("\n");
+ _gcry_secmem_term ();
+ abort ();
+}
+
+void
+gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ),
+ void *opaque )
+{
+ log_handler = f;
+ log_handler_value = opaque;
+}
+
+void
+_gcry_set_log_verbosity( int level )
+{
+ verbosity_level = level;
+}
+
+int
+_gcry_log_verbosity( int level )
+{
+ return verbosity_level >= level;
+}
+
+/****************
+ * This is our log function which prints all log messages to stderr or
+ * using the function defined with gcry_set_log_handler().
+ */
+static void
+_gcry_logv( int level, const char *fmt, va_list arg_ptr )
+{
+ if (log_handler)
+ log_handler (log_handler_value, level, fmt, arg_ptr);
+ else
+ {
+ switch (level)
+ {
+ case GCRY_LOG_CONT: break;
+ case GCRY_LOG_INFO: break;
+ case GCRY_LOG_WARN: break;
+ case GCRY_LOG_ERROR: break;
+ case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break;
+ case GCRY_LOG_BUG: fputs("Ohhhh jeeee: ", stderr); break;
+ case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break;
+ default: fprintf(stderr,"[Unknown log level %d]: ", level ); break;
+ }
+ vfprintf(stderr,fmt,arg_ptr) ;
+ }
+
+ if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG )
+ {
+ fips_signal_fatal_error ("internal error (fatal or bug)");
+ _gcry_secmem_term ();
+ abort ();
+ }
+}
+
+
+void
+_gcry_log( int level, const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( level, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
+void
+_gcry_bug( const char *file, int line, const char *func )
+{
+ _gcry_log( GCRY_LOG_BUG,
+ ("... this is a bug (%s:%d:%s)\n"), file, line, func );
+ abort(); /* never called, but it makes the compiler happy */
+}
+void
+_gcry_assert_failed (const char *expr, const char *file, int line,
+ const char *func)
+{
+ _gcry_log (GCRY_LOG_BUG,
+ ("Assertion `%s' failed (%s:%d:%s)\n"), expr, file, line, func );
+ abort(); /* Never called, but it makes the compiler happy. */
+}
+#else
+void
+_gcry_bug( const char *file, int line )
+{
+ _gcry_log( GCRY_LOG_BUG,
+ _("you found a bug ... (%s:%d)\n"), file, line);
+ abort(); /* never called, but it makes the compiler happy */
+}
+void
+_gcry_assert_failed (const char *expr, const char *file, int line)
+{
+ _gcry_log (GCRY_LOG_BUG,
+ ("Assertion `%s' failed (%s:%d)\n"), expr, file, line);
+ abort(); /* Never called, but it makes the compiler happy. */
+}
+#endif
+
+void
+_gcry_log_info( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+int
+_gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
+{
+ va_list arg_ptr;
+
+ (void)fp;
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
+ va_end(arg_ptr);
+ return 0;
+}
+
+void
+_gcry_log_error( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+void
+_gcry_log_fatal( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr );
+ va_end(arg_ptr);
+ abort(); /* never called, but it makes the compiler happy */
+}
+
+void
+_gcry_log_bug( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr );
+ va_end(arg_ptr);
+ abort(); /* never called, but it makes the compiler happy */
+}
+
+void
+_gcry_log_debug( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+void
+_gcry_log_printf (const char *fmt, ...)
+{
+ va_list arg_ptr;
+
+ if (fmt)
+ {
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr);
+ va_end(arg_ptr);
+ }
+}
+
+/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw
+ dump, with TEXT an empty string, print a trailing linefeed,
+ otherwise print an entire debug line. */
+void
+_gcry_log_printhex (const char *text, const void *buffer, size_t length)
+{
+ if (text && *text)
+ log_debug ("%s ", text);
+ if (length)
+ {
+ const unsigned char *p = buffer;
+ log_printf ("%02X", *p);
+ for (length--, p++; length--; p++)
+ log_printf (" %02X", *p);
+ }
+ if (text)
+ log_printf ("\n");
+}
+
+
+void
+_gcry_burn_stack (int bytes)
+{
+ char buf[64];
+
+ wipememory (buf, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ _gcry_burn_stack (bytes);
+}
diff --git a/grub-core/lib/libgcrypt/src/missing-string.c b/grub-core/lib/libgcrypt/src/missing-string.c
new file mode 100644
index 0000000..4756c00
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/missing-string.c
@@ -0,0 +1,54 @@
+/* missing-string.c - missing string utilities
+ * Copyright (C) 1994, 1998, 1999, 2000, 2001,
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "g10lib.h"
+
+
+#ifndef HAVE_STPCPY
+char *
+stpcpy(char *a,const char *b)
+{
+ while( *b )
+ *a++ = *b++;
+ *a = 0;
+
+ return (char*)a;
+}
+#endif
+
+
+#ifndef HAVE_STRCASECMP
+int
+strcasecmp( const char *a, const char *b )
+{
+ for( ; *a && *b; a++, b++ ) {
+ if( *a != *b && toupper(*a) != toupper(*b) )
+ break;
+ }
+ return *(const byte*)a - *(const byte*)b;
+}
+#endif
diff --git a/grub-core/lib/libgcrypt/src/module.c b/grub-core/lib/libgcrypt/src/module.c
new file mode 100644
index 0000000..32f668d
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/module.c
@@ -0,0 +1,212 @@
+/* module.c - Module management for libgcrypt.
+ * Copyright (C) 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include "g10lib.h"
+
+/* Please match these numbers with the allocated algorithm
+ numbers. */
+#define MODULE_ID_MIN 600
+#define MODULE_ID_LAST 65500
+#define MODULE_ID_USER GCRY_MODULE_ID_USER
+#define MODULE_ID_USER_LAST GCRY_MODULE_ID_USER_LAST
+
+#if MODULE_ID_MIN >= MODULE_ID_USER
+#error Need to implement a different search strategy
+#endif
+
+/* Internal function. Generate a new, unique module ID for a module
+ that should be inserted into the module chain starting at
+ MODULES. */
+static gcry_err_code_t
+_gcry_module_id_new (gcry_module_t modules, unsigned int *id_new)
+{
+ unsigned int mod_id;
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_module_t module;
+
+ /* Search for unused ID. */
+ for (mod_id = MODULE_ID_MIN; mod_id < MODULE_ID_LAST; mod_id++)
+ {
+ if (mod_id == MODULE_ID_USER)
+ {
+ mod_id = MODULE_ID_USER_LAST;
+ continue;
+ }
+
+ /* Search for a module with the current ID. */
+ for (module = modules; module; module = module->next)
+ if (mod_id == module->mod_id)
+ break;
+
+ if (! module)
+ /* None found -> the ID is available for use. */
+ break;
+ }
+
+ if (mod_id < MODULE_ID_LAST)
+ /* Done. */
+ *id_new = mod_id;
+ else
+ /* No free ID found. */
+ err = GPG_ERR_INTERNAL;
+
+ return err;
+}
+
+/* Add a module specification to the list ENTRIES. The new module has
+ it's use-counter set to one. */
+gcry_err_code_t
+_gcry_module_add (gcry_module_t *entries, unsigned int mod_id,
+ void *spec, void *extraspec, gcry_module_t *module)
+{
+ gcry_err_code_t err = 0;
+ gcry_module_t entry;
+
+ if (! mod_id)
+ err = _gcry_module_id_new (*entries, &mod_id);
+
+ if (! err)
+ {
+ entry = gcry_malloc (sizeof (struct gcry_module));
+ if (! entry)
+ err = gpg_err_code_from_errno (errno);
+ }
+
+ if (! err)
+ {
+ /* Fill new module entry. */
+ entry->flags = 0;
+ entry->counter = 1;
+ entry->spec = spec;
+ entry->extraspec = extraspec;
+ entry->mod_id = mod_id;
+
+ /* Link it into the list. */
+ entry->next = *entries;
+ entry->prevp = entries;
+ if (*entries)
+ (*entries)->prevp = &entry->next;
+ *entries = entry;
+
+ /* And give it to the caller. */
+ if (module)
+ *module = entry;
+ }
+ return err;
+}
+
+/* Internal function. Unlink CIPHER_ENTRY from the list of registered
+ ciphers and destroy it. */
+static void
+_gcry_module_drop (gcry_module_t entry)
+{
+ *entry->prevp = entry->next;
+ if (entry->next)
+ entry->next->prevp = entry->prevp;
+
+ gcry_free (entry);
+}
+
+/* Lookup a module specification by it's ID. After a successful
+ lookup, the module has it's resource counter incremented. */
+gcry_module_t
+_gcry_module_lookup_id (gcry_module_t entries, unsigned int mod_id)
+{
+ gcry_module_t entry;
+
+ for (entry = entries; entry; entry = entry->next)
+ if (entry->mod_id == mod_id)
+ {
+ entry->counter++;
+ break;
+ }
+
+ return entry;
+}
+
+/* Lookup a module specification. After a successful lookup, the
+ module has it's resource counter incremented. FUNC is a function
+ provided by the caller, which is responsible for identifying the
+ wanted module. */
+gcry_module_t
+_gcry_module_lookup (gcry_module_t entries, void *data,
+ gcry_module_lookup_t func)
+{
+ gcry_module_t entry;
+
+ for (entry = entries; entry; entry = entry->next)
+ if ((*func) (entry->spec, data))
+ {
+ entry->counter++;
+ break;
+ }
+
+ return entry;
+}
+
+/* Release a module. In case the use-counter reaches zero, destroy
+ the module. Passing MODULE as NULL is a dummy operation (similar
+ to free()). */
+void
+_gcry_module_release (gcry_module_t module)
+{
+ if (module && ! --module->counter)
+ _gcry_module_drop (module);
+}
+
+/* Add a reference to a module. */
+void
+_gcry_module_use (gcry_module_t module)
+{
+ ++module->counter;
+}
+
+/* If LIST is zero, write the number of modules identified by MODULES
+ to LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less cipher modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_err_code_t
+_gcry_module_list (gcry_module_t modules,
+ int *list, int *list_length)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_module_t module;
+ int length, i;
+
+ for (module = modules, length = 0; module; module = module->next, length++);
+
+ if (list)
+ {
+ if (length > *list_length)
+ length = *list_length;
+
+ for (module = modules, i = 0; i < length; module = module->next, i++)
+ list[i] = module->mod_id;
+
+ if (length < *list_length)
+ *list_length = length;
+ }
+ else
+ *list_length = length;
+
+ return err;
+}
diff --git a/grub-core/lib/libgcrypt/src/mpi.h b/grub-core/lib/libgcrypt/src/mpi.h
new file mode 100644
index 0000000..7eebc12
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/mpi.h
@@ -0,0 +1,263 @@
+/* mpi.h - Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998,
+ * 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_H
+#define G10_MPI_H
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "types.h"
+#include "../mpi/mpi-asm-defs.h"
+
+#include "g10lib.h"
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+#error this file should only be used inside libgcrypt
+#endif
+
+#ifndef BITS_PER_MPI_LIMB
+#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
+ typedef unsigned int mpi_limb_t;
+ typedef signed int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
+ typedef unsigned long int mpi_limb_t;
+ typedef signed long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
+ typedef unsigned long long int mpi_limb_t;
+ typedef signed long long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
+ typedef unsigned short int mpi_limb_t;
+ typedef signed short int mpi_limb_signed_t;
+#else
+#error BYTES_PER_MPI_LIMB does not match any C type
+#endif
+#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
+#endif /*BITS_PER_MPI_LIMB*/
+
+#define DBG_MPI _gcry_get_debug_flag( 2 );
+
+struct gcry_mpi
+{
+ int alloced; /* Array size (# of allocated limbs). */
+ int nlimbs; /* Number of valid limbs. */
+ int sign; /* Indicates a negative number and is also used
+ for opaque MPIs to store the length. */
+ unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/
+ /* Bit 2: the limb is a pointer to some m_alloced data.*/
+ mpi_limb_t *d; /* Array with the limbs */
+};
+
+#define MPI_NULL NULL
+
+#define mpi_get_nlimbs(a) ((a)->nlimbs)
+#define mpi_is_neg(a) ((a)->sign)
+
+/*-- mpiutil.c --*/
+
+#ifdef M_DEBUG
+# define mpi_alloc(n) _gcry_mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) )
+# define mpi_alloc_secure(n) _gcry_mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) )
+# define mpi_free(a) _gcry_mpi_debug_free((a), M_DBGINFO(__LINE__) )
+# define mpi_resize(a,b) _gcry_mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) )
+# define mpi_copy(a) _gcry_mpi_debug_copy((a), M_DBGINFO(__LINE__) )
+ gcry_mpi_t _gcry_mpi_debug_alloc( unsigned nlimbs, const char *info );
+ gcry_mpi_t _gcry_mpi_debug_alloc_secure( unsigned nlimbs, const char *info );
+ void _gcry_mpi_debug_free( gcry_mpi_t a, const char *info );
+ void _gcry_mpi_debug_resize( gcry_mpi_t a, unsigned nlimbs, const char *info );
+ gcry_mpi_t _gcry_mpi_debug_copy( gcry_mpi_t a, const char *info );
+#else
+# define mpi_alloc(n) _gcry_mpi_alloc((n) )
+# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) )
+# define mpi_free(a) _gcry_mpi_free((a) )
+# define mpi_resize(a,b) _gcry_mpi_resize((a),(b))
+# define mpi_copy(a) gcry_mpi_copy((a))
+ gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs );
+ gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs );
+ void _gcry_mpi_free( gcry_mpi_t a );
+ void _gcry_mpi_resize( gcry_mpi_t a, unsigned nlimbs );
+ gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a );
+#endif
+
+#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
+#define mpi_is_secure(a) ((a) && ((a)->flags&1))
+#define mpi_clear(a) _gcry_mpi_clear ((a))
+#define mpi_alloc_like(a) _gcry_mpi_alloc_like((a))
+#define mpi_set(a,b) gcry_mpi_set ((a),(b))
+#define mpi_set_ui(a,b) gcry_mpi_set_ui ((a),(b))
+#define mpi_get_ui(a,b) _gcry_mpi_get_ui ((a),(b))
+#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a))
+#define mpi_m_check(a) _gcry_mpi_m_check ((a))
+#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b))
+#define mpi_new(n) gcry_mpi_new ((n))
+#define mpi_snew(n) _gcry_mpi_snew ((n))
+
+void _gcry_mpi_clear( gcry_mpi_t a );
+gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a );
+gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u);
+gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
+void _gcry_mpi_m_check( gcry_mpi_t a );
+void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
+gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
+gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
+
+/*-- mpicoder.c --*/
+void _gcry_log_mpidump( const char *text, gcry_mpi_t a );
+u32 _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid );
+byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
+byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
+void _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer,
+ unsigned int nbytes, int sign );
+
+#define log_mpidump _gcry_log_mpidump
+
+/*-- mpi-add.c --*/
+#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
+#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v))
+#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
+#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
+#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v))
+#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
+
+
+/*-- mpi-mul.c --*/
+#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v))
+#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
+#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v))
+#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m))
+
+
+/*-- mpi-div.c --*/
+#define mpi_fdiv_r_ui(a,b,c) _gcry_mpi_fdiv_r_ui((a),(b),(c))
+#define mpi_fdiv_r(a,b,c) _gcry_mpi_fdiv_r((a),(b),(c))
+#define mpi_fdiv_q(a,b,c) _gcry_mpi_fdiv_q((a),(b),(c))
+#define mpi_fdiv_qr(a,b,c,d) _gcry_mpi_fdiv_qr((a),(b),(c),(d))
+#define mpi_tdiv_r(a,b,c) _gcry_mpi_tdiv_r((a),(b),(c))
+#define mpi_tdiv_qr(a,b,c,d) _gcry_mpi_tdiv_qr((a),(b),(c),(d))
+#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c))
+#define mpi_divisible_ui(a,b) _gcry_mpi_divisible_ui((a),(b))
+
+ulong _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor );
+void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
+void _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
+void _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count );
+int _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor );
+
+
+/*-- mpi-mod.c --*/
+#define mpi_mod(r,a,m) _gcry_mpi_mod ((r), (a), (m))
+#define mpi_barrett_init(m,f) _gcry_mpi_barrett_init ((m),(f))
+#define mpi_barrett_free(c) _gcry_mpi_barrett_free ((c))
+#define mpi_mod_barrett(r,a,c) _gcry_mpi_mod_barrett ((r), (a), (c))
+#define mpi_mul_barrett(r,u,v,c) _gcry_mpi_mul_barrett ((r), (u), (v), (c))
+
+void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+
+/* Context used with Barrett reduction. */
+struct barrett_ctx_s;
+typedef struct barrett_ctx_s *mpi_barrett_t;
+
+mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy);
+void _gcry_mpi_barrett_free (mpi_barrett_t ctx);
+void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx);
+void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
+ mpi_barrett_t ctx);
+
+
+
+/*-- mpi-gcd.c --*/
+
+/*-- mpi-mpow.c --*/
+#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d))
+void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod);
+
+/*-- mpi-cmp.c --*/
+#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b))
+#define mpi_cmp(a,b) gcry_mpi_cmp ((a),(b))
+int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v );
+int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v );
+
+/*-- mpi-scan.c --*/
+#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a))
+int _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx );
+void _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value );
+unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a );
+
+/*-- mpi-bit.c --*/
+#define mpi_normalize(a) _gcry_mpi_normalize ((a))
+#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a))
+#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b))
+#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b))
+#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b))
+#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b))
+#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
+#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c))
+#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c))
+
+void _gcry_mpi_normalize( gcry_mpi_t a );
+
+/*-- mpi-inv.c --*/
+#define mpi_invm(a,b,c) gcry_mpi_invm ((a),(b),(c))
+
+/*-- ec.c --*/
+
+/* Object to represent a point in projective coordinates. */
+struct mpi_point_s;
+typedef struct mpi_point_s mpi_point_t;
+struct mpi_point_s
+{
+ gcry_mpi_t x;
+ gcry_mpi_t y;
+ gcry_mpi_t z;
+};
+
+/* Context used with elliptic curve functions. */
+struct mpi_ec_ctx_s;
+typedef struct mpi_ec_ctx_s *mpi_ec_t;
+
+void _gcry_mpi_ec_point_init (mpi_point_t *p);
+void _gcry_mpi_ec_point_free (mpi_point_t *p);
+mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a);
+void _gcry_mpi_ec_free (mpi_ec_t ctx);
+int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
+ mpi_ec_t ctx);
+void _gcry_mpi_ec_dup_point (mpi_point_t *result,
+ mpi_point_t *point, mpi_ec_t ctx);
+void _gcry_mpi_ec_add_points (mpi_point_t *result,
+ mpi_point_t *p1, mpi_point_t *p2,
+ mpi_ec_t ctx);
+void _gcry_mpi_ec_mul_point (mpi_point_t *result,
+ gcry_mpi_t scalar, mpi_point_t *point,
+ mpi_ec_t ctx);
+
+
+
+#endif /*G10_MPI_H*/
diff --git a/grub-core/lib/libgcrypt/src/secmem.c b/grub-core/lib/libgcrypt/src/secmem.c
new file mode 100644
index 0000000..2beb234
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/secmem.c
@@ -0,0 +1,696 @@
+/* secmem.c - memory allocation from a secure heap
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003, 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stddef.h>
+
+#if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#ifdef USE_CAPABILITIES
+#include <sys/capability.h>
+#endif
+#endif
+
+#include "ath.h"
+#include "g10lib.h"
+#include "secmem.h"
+
+#if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#define MINIMUM_POOL_SIZE 16384
+#define STANDARD_POOL_SIZE 32768
+#define DEFAULT_PAGE_SIZE 4096
+
+typedef struct memblock
+{
+ unsigned size; /* Size of the memory available to the
+ user. */
+ int flags; /* See below. */
+ PROPERLY_ALIGNED_TYPE aligned;
+} memblock_t;
+
+/* This flag specifies that the memory block is in use. */
+#define MB_FLAG_ACTIVE (1 << 0)
+
+/* The pool of secure memory. */
+static void *pool;
+
+/* Size of POOL in bytes. */
+static size_t pool_size;
+
+/* True, if the memory pool is ready for use. May be checked in an
+ atexit function. */
+static volatile int pool_okay;
+
+/* True, if the memory pool is mmapped. */
+static volatile int pool_is_mmapped;
+
+/* FIXME? */
+static int disable_secmem;
+static int show_warning;
+static int not_locked;
+static int no_warning;
+static int suspend_warning;
+
+/* Stats. */
+static unsigned int cur_alloced, cur_blocks;
+
+/* Lock protecting accesses to the memory pool. */
+static ath_mutex_t secmem_lock;
+
+/* Convenient macros. */
+#define SECMEM_LOCK ath_mutex_lock (&secmem_lock)
+#define SECMEM_UNLOCK ath_mutex_unlock (&secmem_lock)
+
+/* The size of the memblock structure; this does not include the
+ memory that is available to the user. */
+#define BLOCK_HEAD_SIZE \
+ offsetof (memblock_t, aligned)
+
+/* Convert an address into the according memory block structure. */
+#define ADDR_TO_BLOCK(addr) \
+ (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE)
+
+/* Check whether P points into the pool. */
+static int
+ptr_into_pool_p (const void *p)
+{
+ /* We need to convert pointers to addresses. This is required by
+ C-99 6.5.8 to avoid undefined behaviour. Using size_t is at
+ least only implementation defined. See also
+ http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
+ */
+ size_t p_addr = (size_t)p;
+ size_t pool_addr = (size_t)pool;
+
+ return p_addr >= pool_addr && p_addr < pool_addr+pool_size;
+}
+
+/* Update the stats. */
+static void
+stats_update (size_t add, size_t sub)
+{
+ if (add)
+ {
+ cur_alloced += add;
+ cur_blocks++;
+ }
+ if (sub)
+ {
+ cur_alloced -= sub;
+ cur_blocks--;
+ }
+}
+
+/* Return the block following MB or NULL, if MB is the last block. */
+static memblock_t *
+mb_get_next (memblock_t *mb)
+{
+ memblock_t *mb_next;
+
+ mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size);
+
+ if (! ptr_into_pool_p (mb_next))
+ mb_next = NULL;
+
+ return mb_next;
+}
+
+/* Return the block preceding MB or NULL, if MB is the first
+ block. */
+static memblock_t *
+mb_get_prev (memblock_t *mb)
+{
+ memblock_t *mb_prev, *mb_next;
+
+ if (mb == pool)
+ mb_prev = NULL;
+ else
+ {
+ mb_prev = (memblock_t *) pool;
+ while (1)
+ {
+ mb_next = mb_get_next (mb_prev);
+ if (mb_next == mb)
+ break;
+ else
+ mb_prev = mb_next;
+ }
+ }
+
+ return mb_prev;
+}
+
+/* If the preceding block of MB and/or the following block of MB
+ exist and are not active, merge them to form a bigger block. */
+static void
+mb_merge (memblock_t *mb)
+{
+ memblock_t *mb_prev, *mb_next;
+
+ mb_prev = mb_get_prev (mb);
+ mb_next = mb_get_next (mb);
+
+ if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE)))
+ {
+ mb_prev->size += BLOCK_HEAD_SIZE + mb->size;
+ mb = mb_prev;
+ }
+ if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE)))
+ mb->size += BLOCK_HEAD_SIZE + mb_next->size;
+}
+
+/* Return a new block, which can hold SIZE bytes. */
+static memblock_t *
+mb_get_new (memblock_t *block, size_t size)
+{
+ memblock_t *mb, *mb_split;
+
+ for (mb = block; ptr_into_pool_p (mb); mb = mb_get_next (mb))
+ if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size)
+ {
+ /* Found a free block. */
+ mb->flags |= MB_FLAG_ACTIVE;
+
+ if (mb->size - size > BLOCK_HEAD_SIZE)
+ {
+ /* Split block. */
+
+ mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size);
+ mb_split->size = mb->size - size - BLOCK_HEAD_SIZE;
+ mb_split->flags = 0;
+
+ mb->size = size;
+
+ mb_merge (mb_split);
+
+ }
+
+ break;
+ }
+
+ if (! ptr_into_pool_p (mb))
+ {
+ gpg_err_set_errno (ENOMEM);
+ mb = NULL;
+ }
+
+ return mb;
+}
+
+/* Print a warning message. */
+static void
+print_warn (void)
+{
+ if (!no_warning)
+ log_info (_("Warning: using insecure memory!\n"));
+}
+
+/* Lock the memory pages into core and drop privileges. */
+static void
+lock_pool (void *p, size_t n)
+{
+#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
+ int err;
+
+ cap_set_proc (cap_from_text ("cap_ipc_lock+ep"));
+ err = mlock (p, n);
+ if (err && errno)
+ err = errno;
+ cap_set_proc (cap_from_text ("cap_ipc_lock+p"));
+
+ if (err)
+ {
+ if (errno != EPERM
+#ifdef EAGAIN /* OpenBSD returns this */
+ && errno != EAGAIN
+#endif
+#ifdef ENOSYS /* Some SCOs return this (function not implemented) */
+ && errno != ENOSYS
+#endif
+#ifdef ENOMEM /* Linux might return this. */
+ && errno != ENOMEM
+#endif
+ )
+ log_error ("can't lock memory: %s\n", strerror (err));
+ show_warning = 1;
+ not_locked = 1;
+ }
+
+#elif defined(HAVE_MLOCK)
+ uid_t uid;
+ int err;
+
+ uid = getuid ();
+
+#ifdef HAVE_BROKEN_MLOCK
+ /* Under HP/UX mlock segfaults if called by non-root. Note, we have
+ noch checked whether mlock does really work under AIX where we
+ also detected a broken nlock. Note further, that using plock ()
+ is not a good idea under AIX. */
+ if (uid)
+ {
+ errno = EPERM;
+ err = errno;
+ }
+ else
+ {
+ err = mlock (p, n);
+ if (err && errno)
+ err = errno;
+ }
+#else /* !HAVE_BROKEN_MLOCK */
+ err = mlock (p, n);
+ if (err && errno)
+ err = errno;
+#endif /* !HAVE_BROKEN_MLOCK */
+
+ if (uid && ! geteuid ())
+ {
+ /* check that we really dropped the privs.
+ * Note: setuid(0) should always fail */
+ if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+ log_fatal ("failed to reset uid: %s\n", strerror (errno));
+ }
+
+ if (err)
+ {
+ if (errno != EPERM
+#ifdef EAGAIN /* OpenBSD returns this. */
+ && errno != EAGAIN
+#endif
+#ifdef ENOSYS /* Some SCOs return this (function not implemented). */
+ && errno != ENOSYS
+#endif
+#ifdef ENOMEM /* Linux might return this. */
+ && errno != ENOMEM
+#endif
+ )
+ log_error ("can't lock memory: %s\n", strerror (err));
+ show_warning = 1;
+ not_locked = 1;
+ }
+
+#elif defined ( __QNX__ )
+ /* QNX does not page at all, so the whole secure memory stuff does
+ * not make much sense. However it is still of use because it
+ * wipes out the memory on a free().
+ * Therefore it is sufficient to suppress the warning. */
+ (void)p;
+ (void)n;
+#elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
+ /* It does not make sense to print such a warning, given the fact that
+ * this whole Windows !@#$% and their user base are inherently insecure. */
+ (void)p;
+ (void)n;
+#elif defined (__riscos__)
+ /* No virtual memory on RISC OS, so no pages are swapped to disc,
+ * besides we don't have mmap, so we don't use it! ;-)
+ * But don't complain, as explained above. */
+ (void)p;
+ (void)n;
+#else
+ (void)p;
+ (void)n;
+ log_info ("Please note that you don't have secure memory on this system\n");
+#endif
+}
+
+/* Initialize POOL. */
+static void
+init_pool (size_t n)
+{
+ size_t pgsize;
+ long int pgsize_val;
+ memblock_t *mb;
+
+ pool_size = n;
+
+ if (disable_secmem)
+ log_bug ("secure memory is disabled");
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pgsize_val = sysconf (_SC_PAGESIZE);
+#elif defined(HAVE_GETPAGESIZE)
+ pgsize_val = getpagesize ();
+#else
+ pgsize_val = -1;
+#endif
+ pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
+
+
+#if HAVE_MMAP
+ pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1);
+#ifdef MAP_ANONYMOUS
+ pool = mmap (0, pool_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#else /* map /dev/zero instead */
+ {
+ int fd;
+
+ fd = open ("/dev/zero", O_RDWR);
+ if (fd == -1)
+ {
+ log_error ("can't open /dev/zero: %s\n", strerror (errno));
+ pool = (void *) -1;
+ }
+ else
+ {
+ pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ close (fd);
+ }
+ }
+#endif
+ if (pool == (void *) -1)
+ log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
+ (unsigned) pool_size, strerror (errno));
+ else
+ {
+ pool_is_mmapped = 1;
+ pool_okay = 1;
+ }
+
+#endif
+ if (!pool_okay)
+ {
+ pool = malloc (pool_size);
+ if (!pool)
+ log_fatal ("can't allocate memory pool of %u bytes\n",
+ (unsigned) pool_size);
+ else
+ pool_okay = 1;
+ }
+
+ /* Initialize first memory block. */
+ mb = (memblock_t *) pool;
+ mb->size = pool_size;
+ mb->flags = 0;
+}
+
+void
+_gcry_secmem_set_flags (unsigned flags)
+{
+ int was_susp;
+
+ SECMEM_LOCK;
+
+ was_susp = suspend_warning;
+ no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
+ suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
+
+ /* and now issue the warning if it is not longer suspended */
+ if (was_susp && !suspend_warning && show_warning)
+ {
+ show_warning = 0;
+ print_warn ();
+ }
+
+ SECMEM_UNLOCK;
+}
+
+unsigned int
+_gcry_secmem_get_flags (void)
+{
+ unsigned flags;
+
+ SECMEM_LOCK;
+
+ flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
+ flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
+ flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
+
+ SECMEM_UNLOCK;
+
+ return flags;
+}
+
+
+/* See _gcry_secmem_init. This function is expected to be called with
+ the secmem lock held. */
+static void
+secmem_init (size_t n)
+{
+ if (!n)
+ {
+#ifdef USE_CAPABILITIES
+ /* drop all capabilities */
+ cap_set_proc (cap_from_text ("all-eip"));
+
+#elif !defined(HAVE_DOSISH_SYSTEM)
+ uid_t uid;
+
+ disable_secmem = 1;
+ uid = getuid ();
+ if (uid != geteuid ())
+ {
+ if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+ log_fatal ("failed to drop setuid\n");
+ }
+#endif
+ }
+ else
+ {
+ if (n < MINIMUM_POOL_SIZE)
+ n = MINIMUM_POOL_SIZE;
+ if (! pool_okay)
+ {
+ init_pool (n);
+ lock_pool (pool, n);
+ }
+ else
+ log_error ("Oops, secure memory pool already initialized\n");
+ }
+}
+
+
+
+/* Initialize the secure memory system. If running with the necessary
+ privileges, the secure memory pool will be locked into the core in
+ order to prevent page-outs of the data. Furthermore allocated
+ secure memory will be wiped out when released. */
+void
+_gcry_secmem_init (size_t n)
+{
+ SECMEM_LOCK;
+
+ secmem_init (n);
+
+ SECMEM_UNLOCK;
+}
+
+
+static void *
+_gcry_secmem_malloc_internal (size_t size)
+{
+ memblock_t *mb;
+
+ if (!pool_okay)
+ {
+ /* Try to initialize the pool if the user forgot about it. */
+ secmem_init (STANDARD_POOL_SIZE);
+ if (!pool_okay)
+ {
+ log_info (_("operation is not possible without "
+ "initialized secure memory\n"));
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ }
+ if (not_locked && fips_mode ())
+ {
+ log_info (_("secure memory pool is not locked while in FIPS mode\n"));
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ if (show_warning && !suspend_warning)
+ {
+ show_warning = 0;
+ print_warn ();
+ }
+
+ /* Blocks are always a multiple of 32. */
+ size = ((size + 31) / 32) * 32;
+
+ mb = mb_get_new ((memblock_t *) pool, size);
+ if (mb)
+ stats_update (size, 0);
+
+ return mb ? &mb->aligned.c : NULL;
+}
+
+void *
+_gcry_secmem_malloc (size_t size)
+{
+ void *p;
+
+ SECMEM_LOCK;
+ p = _gcry_secmem_malloc_internal (size);
+ SECMEM_UNLOCK;
+
+ return p;
+}
+
+static void
+_gcry_secmem_free_internal (void *a)
+{
+ memblock_t *mb;
+ int size;
+
+ if (!a)
+ return;
+
+ mb = ADDR_TO_BLOCK (a);
+ size = mb->size;
+
+ /* This does not make much sense: probably this memory is held in the
+ * cache. We do it anyway: */
+#define MB_WIPE_OUT(byte) \
+ wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size);
+
+ MB_WIPE_OUT (0xff);
+ MB_WIPE_OUT (0xaa);
+ MB_WIPE_OUT (0x55);
+ MB_WIPE_OUT (0x00);
+
+ stats_update (0, size);
+
+ mb->flags &= ~MB_FLAG_ACTIVE;
+
+ /* Update stats. */
+
+ mb_merge (mb);
+}
+
+/* Wipe out and release memory. */
+void
+_gcry_secmem_free (void *a)
+{
+ SECMEM_LOCK;
+ _gcry_secmem_free_internal (a);
+ SECMEM_UNLOCK;
+}
+
+/* Realloc memory. */
+void *
+_gcry_secmem_realloc (void *p, size_t newsize)
+{
+ memblock_t *mb;
+ size_t size;
+ void *a;
+
+ SECMEM_LOCK;
+
+ mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c));
+ size = mb->size;
+ if (newsize < size)
+ {
+ /* It is easier to not shrink the memory. */
+ a = p;
+ }
+ else
+ {
+ a = _gcry_secmem_malloc_internal (newsize);
+ if (a)
+ {
+ memcpy (a, p, size);
+ memset ((char *) a + size, 0, newsize - size);
+ _gcry_secmem_free_internal (p);
+ }
+ }
+
+ SECMEM_UNLOCK;
+
+ return a;
+}
+
+
+/* Return true if P points into the secure memory area. */
+int
+_gcry_private_is_secure (const void *p)
+{
+ return pool_okay && ptr_into_pool_p (p);
+}
+
+
+/****************
+ * Warning: This code might be called by an interrupt handler
+ * and frankly, there should really be such a handler,
+ * to make sure that the memory is wiped out.
+ * We hope that the OS wipes out mlocked memory after
+ * receiving a SIGKILL - it really should do so, otherwise
+ * there is no chance to get the secure memory cleaned.
+ */
+void
+_gcry_secmem_term ()
+{
+ if (!pool_okay)
+ return;
+
+ wipememory2 (pool, 0xff, pool_size);
+ wipememory2 (pool, 0xaa, pool_size);
+ wipememory2 (pool, 0x55, pool_size);
+ wipememory2 (pool, 0x00, pool_size);
+#if HAVE_MMAP
+ if (pool_is_mmapped)
+ munmap (pool, pool_size);
+#endif
+ pool = NULL;
+ pool_okay = 0;
+ pool_size = 0;
+ not_locked = 0;
+}
+
+
+void
+_gcry_secmem_dump_stats ()
+{
+#if 1
+ SECMEM_LOCK;
+
+ if (pool_okay)
+ log_info ("secmem usage: %u/%lu bytes in %u blocks\n",
+ cur_alloced, (unsigned long)pool_size, cur_blocks);
+ SECMEM_UNLOCK;
+#else
+ memblock_t *mb;
+ int i;
+
+ SECMEM_LOCK;
+
+ for (i = 0, mb = (memblock_t *) pool;
+ ptr_into_pool_p (mb);
+ mb = mb_get_next (mb), i++)
+ log_info ("SECMEM: [%s] block: %i; size: %i\n",
+ (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
+ i,
+ mb->size);
+ SECMEM_UNLOCK;
+#endif
+}
diff --git a/grub-core/lib/libgcrypt/src/secmem.h b/grub-core/lib/libgcrypt/src/secmem.h
new file mode 100644
index 0000000..29e151a
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/secmem.h
@@ -0,0 +1,39 @@
+/* secmem.h - internal definitions for secmem
+ * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef G10_SECMEM_H
+#define G10_SECMEM_H 1
+
+void _gcry_secmem_init (size_t npool);
+void _gcry_secmem_term (void);
+void *_gcry_secmem_malloc (size_t size) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_secmem_realloc (void *a, size_t newsize);
+void _gcry_secmem_free (void *a);
+void _gcry_secmem_dump_stats (void);
+void _gcry_secmem_set_flags (unsigned flags);
+unsigned _gcry_secmem_get_flags(void);
+int _gcry_private_is_secure (const void *p);
+
+/* Flags for _gcry_secmem_{set,get}_flags. */
+#define GCRY_SECMEM_FLAG_NO_WARNING (1 << 0)
+#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
+#define GCRY_SECMEM_FLAG_NOT_LOCKED (1 << 2)
+
+#endif /* G10_SECMEM_H */
diff --git a/grub-core/lib/libgcrypt/src/sexp.c b/grub-core/lib/libgcrypt/src/sexp.c
new file mode 100644
index 0000000..0877773
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/sexp.c
@@ -0,0 +1,2033 @@
+/* sexp.c - S-Expression handling
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003,
+ * 2004, 2006, 2007, 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+
+#define GCRYPT_NO_MPI_MACROS 1
+#include "g10lib.h"
+
+typedef struct gcry_sexp *NODE;
+typedef unsigned short DATALEN;
+
+struct gcry_sexp
+{
+ byte d[1];
+};
+
+#define ST_STOP 0
+#define ST_DATA 1 /* datalen follows */
+#define ST_HINT 2 /* datalen follows */
+#define ST_OPEN 3
+#define ST_CLOSE 4
+
+/* the atoi macros assume that the buffer has only valid digits */
+#define atoi_1(p) (*(p) - '0' )
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
+#define TOKEN_SPECIALS "-./_:*+="
+
+static gcry_error_t
+vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, va_list arg_ptr);
+
+static gcry_error_t
+sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, ...);
+
+/* Return true if P points to a byte containing a whitespace according
+ to the S-expressions definition. */
+#undef whitespacep
+static GPG_ERR_INLINE int
+whitespacep (const char *p)
+{
+ switch (*p)
+ {
+ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
+ default: return 0;
+ }
+}
+
+
+#if 0
+static void
+dump_mpi( gcry_mpi_t a )
+{
+ char buffer[1000];
+ size_t n = 1000;
+
+ if( !a )
+ fputs("[no MPI]", stderr );
+ else if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) )
+ fputs("[MPI too large to print]", stderr );
+ else
+ fputs( buffer, stderr );
+}
+#endif
+
+static void
+dump_string (const byte *p, size_t n, int delim )
+{
+ for (; n; n--, p++ )
+ {
+ if ((*p & 0x80) || iscntrl( *p ) || *p == delim )
+ {
+ if( *p == '\n' )
+ log_printf ("\\n");
+ else if( *p == '\r' )
+ log_printf ("\\r");
+ else if( *p == '\f' )
+ log_printf ("\\f");
+ else if( *p == '\v' )
+ log_printf ("\\v");
+ else if( *p == '\b' )
+ log_printf ("\\b");
+ else if( !*p )
+ log_printf ("\\0");
+ else
+ log_printf ("\\x%02x", *p );
+ }
+ else
+ log_printf ("%c", *p);
+ }
+}
+
+
+void
+gcry_sexp_dump (const gcry_sexp_t a)
+{
+ const byte *p;
+ int indent = 0;
+ int type;
+
+ if (!a)
+ {
+ log_printf ( "[nil]\n");
+ return;
+ }
+
+ p = a->d;
+ while ( (type = *p) != ST_STOP )
+ {
+ p++;
+ switch ( type )
+ {
+ case ST_OPEN:
+ log_printf ("%*s[open]\n", 2*indent, "");
+ indent++;
+ break;
+ case ST_CLOSE:
+ if( indent )
+ indent--;
+ log_printf ("%*s[close]\n", 2*indent, "");
+ break;
+ case ST_DATA: {
+ DATALEN n;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ log_printf ("%*s[data=\"", 2*indent, "" );
+ dump_string (p, n, '\"' );
+ log_printf ("\"]\n");
+ p += n;
+ }
+ break;
+ default:
+ log_printf ("%*s[unknown tag %d]\n", 2*indent, "", type);
+ break;
+ }
+ }
+}
+
+/****************
+ * Pass list through except when it is an empty list - in that case
+ * return NULL and release the passed list.
+ */
+static gcry_sexp_t
+normalize ( gcry_sexp_t list )
+{
+ unsigned char *p;
+
+ if ( !list )
+ return NULL;
+ p = list->d;
+ if ( *p == ST_STOP )
+ {
+ /* this is "" */
+ gcry_sexp_release ( list );
+ return NULL;
+ }
+ if ( *p == ST_OPEN && p[1] == ST_CLOSE )
+ {
+ /* this is "()" */
+ gcry_sexp_release ( list );
+ return NULL;
+ }
+
+ return list;
+}
+
+/* Create a new S-expression object by reading LENGTH bytes from
+ BUFFER, assuming it is canonical encoded or autodetected encoding
+ when AUTODETECT is set to 1. With FREEFNC not NULL, ownership of
+ the buffer is transferred to the newly created object. FREEFNC
+ should be the freefnc used to release BUFFER; there is no guarantee
+ at which point this function is called; most likey you want to use
+ free() or gcry_free().
+
+ Passing LENGTH and AUTODETECT as 0 is allowed to indicate that
+ BUFFER points to a valid canonical encoded S-expression. A LENGTH
+ of 0 and AUTODETECT 1 indicates that buffer points to a
+ null-terminated string.
+
+ This function returns 0 and and the pointer to the new object in
+ RETSEXP or an error code in which case RETSEXP is set to NULL. */
+gcry_error_t
+gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
+ int autodetect, void (*freefnc)(void*) )
+{
+ gcry_error_t errcode;
+ gcry_sexp_t se;
+
+ if (!retsexp)
+ return gcry_error (GPG_ERR_INV_ARG);
+ *retsexp = NULL;
+ if (autodetect < 0 || autodetect > 1 || !buffer)
+ return gcry_error (GPG_ERR_INV_ARG);
+
+ if (!length && !autodetect)
+ { /* What a brave caller to assume that there is really a canonical
+ encoded S-expression in buffer */
+ length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode);
+ if (!length)
+ return errcode;
+ }
+ else if (!length && autodetect)
+ { /* buffer is a string */
+ length = strlen ((char *)buffer);
+ }
+
+ errcode = sexp_sscan (&se, NULL, buffer, length, 0, NULL);
+ if (errcode)
+ return errcode;
+
+ *retsexp = se;
+ if (freefnc)
+ {
+ /* For now we release the buffer immediately. As soon as we
+ have changed the internal represenation of S-expression to
+ the canoncial format - which has the advantage of faster
+ parsing - we will use this function as a closure in our
+ GCRYSEXP object and use the BUFFER directly. */
+ freefnc (buffer);
+ }
+ return gcry_error (GPG_ERR_NO_ERROR);
+}
+
+/* Same as gcry_sexp_create but don't transfer ownership */
+gcry_error_t
+gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
+ int autodetect)
+{
+ return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
+}
+
+
+/****************
+ * Release resource of the given SEXP object.
+ */
+void
+gcry_sexp_release( gcry_sexp_t sexp )
+{
+ if (sexp)
+ {
+ if (gcry_is_secure (sexp))
+ {
+ /* Extra paranoid wiping. */
+ const byte *p = sexp->d;
+ int type;
+
+ while ( (type = *p) != ST_STOP )
+ {
+ p++;
+ switch ( type )
+ {
+ case ST_OPEN:
+ break;
+ case ST_CLOSE:
+ break;
+ case ST_DATA:
+ {
+ DATALEN n;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ p += n;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ wipememory (sexp->d, p - sexp->d);
+ }
+ gcry_free ( sexp );
+ }
+}
+
+
+/****************
+ * Make a pair from lists a and b, don't use a or b later on.
+ * Special behaviour: If one is a single element list we put the
+ * element straight into the new pair.
+ */
+gcry_sexp_t
+gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
+{
+ (void)a;
+ (void)b;
+
+ /* NYI: Implementation should be quite easy with our new data
+ representation */
+ BUG ();
+ return NULL;
+}
+
+
+/****************
+ * Make a list from all items in the array the end of the array is marked
+ * with a NULL.
+ */
+gcry_sexp_t
+gcry_sexp_alist( const gcry_sexp_t *array )
+{
+ (void)array;
+
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+/****************
+ * Make a list from all items, the end of list is indicated by a NULL
+ */
+gcry_sexp_t
+gcry_sexp_vlist( const gcry_sexp_t a, ... )
+{
+ (void)a;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+
+/****************
+ * Append n to the list a
+ * Returns: a new ist (which maybe a)
+ */
+gcry_sexp_t
+gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n )
+{
+ (void)a;
+ (void)n;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+gcry_sexp_t
+gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n )
+{
+ (void)a;
+ (void)n;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+
+
+/****************
+ * Locate token in a list. The token must be the car of a sublist.
+ * Returns: A new list with this sublist or NULL if not found.
+ */
+gcry_sexp_t
+gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
+{
+ const byte *p;
+ DATALEN n;
+
+ if ( !list )
+ return NULL;
+
+ if ( !toklen )
+ toklen = strlen(tok);
+
+ p = list->d;
+ while ( *p != ST_STOP )
+ {
+ if ( *p == ST_OPEN && p[1] == ST_DATA )
+ {
+ const byte *head = p;
+
+ p += 2;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ if ( n == toklen && !memcmp( p, tok, toklen ) )
+ { /* found it */
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 1;
+
+ /* Look for the end of the list. */
+ for ( p += n; level; p++ )
+ {
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--; /* Compensate for later increment. */
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ BUG ();
+ }
+ }
+ n = p - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n );
+ if (!newlist)
+ {
+ /* No way to return an error code, so we can only
+ return Not Found. */
+ return NULL;
+ }
+ d = newlist->d;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_STOP;
+ return normalize ( newlist );
+ }
+ p += n;
+ }
+ else if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n ); p += sizeof n;
+ p += n;
+ }
+ else
+ p++;
+ }
+ return NULL;
+}
+
+/****************
+ * Return the length of the given list
+ */
+int
+gcry_sexp_length( const gcry_sexp_t list )
+{
+ const byte *p;
+ DATALEN n;
+ int type;
+ int length = 0;
+ int level = 0;
+
+ if ( !list )
+ return 0;
+
+ p = list->d;
+ while ( (type=*p) != ST_STOP ) {
+ p++;
+ if ( type == ST_DATA ) {
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n + n;
+ if ( level == 1 )
+ length++;
+ }
+ else if ( type == ST_OPEN ) {
+ if ( level == 1 )
+ length++;
+ level++;
+ }
+ else if ( type == ST_CLOSE ) {
+ level--;
+ }
+ }
+ return length;
+}
+
+
+/* Return the internal lengths offset of LIST. That is the size of
+ the buffer from the first ST_OPEN, which is retruned at R_OFF, to
+ the corresponding ST_CLOSE inclusive. */
+static size_t
+get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
+{
+ const unsigned char *p;
+ DATALEN n;
+ int type;
+ int level = 0;
+
+ *r_off = 0;
+ if (list)
+ {
+ p = list->d;
+ while ( (type=*p) != ST_STOP )
+ {
+ p++;
+ if (type == ST_DATA)
+ {
+ memcpy (&n, p, sizeof n);
+ p += sizeof n + n;
+ }
+ else if (type == ST_OPEN)
+ {
+ if (!level)
+ *r_off = (p-1) - list->d;
+ level++;
+ }
+ else if ( type == ST_CLOSE )
+ {
+ level--;
+ if (!level)
+ return p - list->d;
+ }
+ }
+ }
+ return 0; /* Not a proper list. */
+}
+
+
+
+/* Extract the CAR of the given list. May return NULL for bad lists
+ or memory failure. */
+gcry_sexp_t
+gcry_sexp_nth( const gcry_sexp_t list, int number )
+{
+ const byte *p;
+ DATALEN n;
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 0;
+
+ if ( !list || list->d[0] != ST_OPEN )
+ return NULL;
+ p = list->d;
+
+ while ( number > 0 ) {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ }
+ p++;
+
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, p, sizeof n ); p += sizeof n;
+ newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ memcpy ( d, p, n ); d += n;
+ *d++ = ST_STOP;
+ }
+ else if ( *p == ST_OPEN ) {
+ const byte *head = p;
+
+ level = 1;
+ do {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ }
+ else if ( *p == ST_STOP ) {
+ BUG ();
+ }
+ } while ( level );
+ n = p + 1 - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_STOP;
+ }
+ else
+ newlist = NULL;
+
+ return normalize (newlist);
+}
+
+gcry_sexp_t
+gcry_sexp_car( const gcry_sexp_t list )
+{
+ return gcry_sexp_nth ( list, 0 );
+}
+
+
+/* Helper to get data from the car. The returned value is valid as
+ long as the list is not modified. */
+static const char *
+sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
+{
+ const byte *p;
+ DATALEN n;
+ int level = 0;
+
+ *datalen = 0;
+ if ( !list )
+ return NULL;
+
+ p = list->d;
+ if ( *p == ST_OPEN )
+ p++; /* Yep, a list. */
+ else if (number)
+ return NULL; /* Not a list but N > 0 requested. */
+
+ /* Skip over N elements. */
+ while ( number > 0 )
+ {
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ return NULL;
+ }
+ p++;
+ }
+
+ /* If this is data, return it. */
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ *datalen = n;
+ return (const char*)p + sizeof n;
+ }
+
+ return NULL;
+}
+
+
+/* Get data from the car. The returned value is valid as long as the
+ list is not modified. */
+const char *
+gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
+{
+ return sexp_nth_data (list, number, datalen);
+}
+
+
+/* Get a string from the car. The returned value is a malloced string
+ and needs to be freed by the caller. */
+char *
+gcry_sexp_nth_string (const gcry_sexp_t list, int number)
+{
+ const char *s;
+ size_t n;
+ char *buf;
+
+ s = sexp_nth_data (list, number, &n);
+ if (!s || n < 1 || (n+1) < 1)
+ return NULL;
+ buf = gcry_malloc (n+1);
+ if (!buf)
+ return NULL;
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ return buf;
+}
+
+/*
+ * Get a MPI from the car
+ */
+gcry_mpi_t
+gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
+{
+ const char *s;
+ size_t n;
+ gcry_mpi_t a;
+
+ if ( !mpifmt )
+ mpifmt = GCRYMPI_FMT_STD;
+
+ s = sexp_nth_data (list, number, &n);
+ if (!s)
+ return NULL;
+
+ if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) )
+ return NULL;
+
+ return a;
+}
+
+
+/****************
+ * Get the CDR
+ */
+gcry_sexp_t
+gcry_sexp_cdr( const gcry_sexp_t list )
+{
+ const byte *p;
+ const byte *head;
+ DATALEN n;
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 0;
+ int skip = 1;
+
+ if ( !list || list->d[0] != ST_OPEN )
+ return NULL;
+ p = list->d;
+
+ while ( skip > 0 ) {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ skip--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ if ( !level )
+ skip--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ }
+ p++;
+
+ head = p;
+ level = 0;
+ do {
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ p++;
+ } while ( level );
+ n = p - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n + 2 );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ *d++ = ST_OPEN;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_CLOSE;
+ *d++ = ST_STOP;
+
+ return normalize (newlist);
+}
+
+gcry_sexp_t
+gcry_sexp_cadr ( const gcry_sexp_t list )
+{
+ gcry_sexp_t a, b;
+
+ a = gcry_sexp_cdr ( list );
+ b = gcry_sexp_car ( a );
+ gcry_sexp_release ( a );
+ return b;
+}
+
+
+
+static int
+hextobyte( const byte *s )
+{
+ int c=0;
+
+ if( *s >= '0' && *s <= '9' )
+ c = 16 * (*s - '0');
+ else if( *s >= 'A' && *s <= 'F' )
+ c = 16 * (10 + *s - 'A');
+ else if( *s >= 'a' && *s <= 'f' ) {
+ c = 16 * (10 + *s - 'a');
+ }
+ s++;
+ if( *s >= '0' && *s <= '9' )
+ c += *s - '0';
+ else if( *s >= 'A' && *s <= 'F' )
+ c += 10 + *s - 'A';
+ else if( *s >= 'a' && *s <= 'f' ) {
+ c += 10 + *s - 'a';
+ }
+ return c;
+}
+
+struct make_space_ctx {
+ gcry_sexp_t sexp;
+ size_t allocated;
+ byte *pos;
+};
+
+static gpg_err_code_t
+make_space ( struct make_space_ctx *c, size_t n )
+{
+ size_t used = c->pos - c->sexp->d;
+
+ if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
+ {
+ gcry_sexp_t newsexp;
+ byte *newhead;
+ size_t newsize;
+
+ newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
+ if (newsize <= c->allocated)
+ return GPG_ERR_TOO_LARGE;
+ newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
+ if (!newsexp)
+ return gpg_err_code_from_errno (errno);
+ c->allocated = newsize;
+ newhead = newsexp->d;
+ c->pos = newhead + used;
+ c->sexp = newsexp;
+ }
+ return 0;
+}
+
+
+/* Unquote STRING of LENGTH and store it into BUF. The surrounding
+ quotes are must already be removed from STRING. We assume that the
+ quoted string is syntacillay correct. */
+static size_t
+unquote_string (const char *string, size_t length, unsigned char *buf)
+{
+ int esc = 0;
+ const unsigned char *s = (const unsigned char*)string;
+ unsigned char *d = buf;
+ size_t n = length;
+
+ for (; n; n--, s++)
+ {
+ if (esc)
+ {
+ switch (*s)
+ {
+ case 'b': *d++ = '\b'; break;
+ case 't': *d++ = '\t'; break;
+ case 'v': *d++ = '\v'; break;
+ case 'n': *d++ = '\n'; break;
+ case 'f': *d++ = '\f'; break;
+ case 'r': *d++ = '\r'; break;
+ case '"': *d++ = '\"'; break;
+ case '\'': *d++ = '\''; break;
+ case '\\': *d++ = '\\'; break;
+
+ case '\r': /* ignore CR[,LF] */
+ if (n>1 && s[1] == '\n')
+ {
+ s++; n--;
+ }
+ break;
+
+ case '\n': /* ignore LF[,CR] */
+ if (n>1 && s[1] == '\r')
+ {
+ s++; n--;
+ }
+ break;
+
+ case 'x': /* hex value */
+ if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
+ {
+ s++; n--;
+ *d++ = xtoi_2 (s);
+ s++; n--;
+ }
+ break;
+
+ default:
+ if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
+ {
+ *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
+ s += 2;
+ n -= 2;
+ }
+ break;
+ }
+ esc = 0;
+ }
+ else if( *s == '\\' )
+ esc = 1;
+ else
+ *d++ = *s;
+ }
+
+ return d - buf;
+}
+
+/****************
+ * Scan the provided buffer and return the S expression in our internal
+ * format. Returns a newly allocated expression. If erroff is not NULL and
+ * a parsing error has occurred, the offset into buffer will be returned.
+ * If ARGFLAG is true, the function supports some printf like
+ * expressions.
+ * These are:
+ * %m - MPI
+ * %s - string (no autoswitch to secure allocation)
+ * %d - integer stored as string (no autoswitch to secure allocation)
+ * %b - memory buffer; this takes _two_ arguments: an integer with the
+ * length of the buffer and a pointer to the buffer.
+ * %S - Copy an gcry_sexp_t here. The S-expression needs to be a
+ * regular one, starting with a parenthesis.
+ * (no autoswitch to secure allocation)
+ * all other format elements are currently not defined and return an error.
+ * this includes the "%%" sequence becauce the percent sign is not an
+ * allowed character.
+ * FIXME: We should find a way to store the secure-MPIs not in the string
+ * but as reference to somewhere - this can help us to save huge amounts
+ * of secure memory. The problem is, that if only one element is secure, all
+ * other elements are automagicaly copied to secure memory too, so the most
+ * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
+ * regardless whether it is needed or not.
+ */
+static gcry_error_t
+vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, va_list arg_ptr)
+{
+ gcry_err_code_t err = 0;
+ static const char tokenchars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-./_:*+=";
+ const char *p;
+ size_t n;
+ const char *digptr = NULL;
+ const char *quoted = NULL;
+ const char *tokenp = NULL;
+ const char *hexfmt = NULL;
+ const char *base64 = NULL;
+ const char *disphint = NULL;
+ const char *percent = NULL;
+ int hexcount = 0;
+ int quoted_esc = 0;
+ int datalen = 0;
+ size_t dummy_erroff;
+ struct make_space_ctx c;
+ int arg_counter = 0;
+ int level = 0;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+
+ /* Depending on whether ARG_LIST is non-zero or not, this macro gives
+ us the next argument, either from the variable argument list as
+ specified by ARG_PTR or from the argument array ARG_LIST. */
+#define ARG_NEXT(storage, type) \
+ do \
+ { \
+ if (!arg_list) \
+ storage = va_arg (arg_ptr, type); \
+ else \
+ storage = *((type *) (arg_list[arg_counter++])); \
+ } \
+ while (0)
+
+ /* The MAKE_SPACE macro is used before each store operation to
+ ensure that the buffer is large enough. It requires a global
+ context named C and jumps out to the label LEAVE on error! It
+ also sets ERROFF using the variables BUFFER and P. */
+#define MAKE_SPACE(n) do { \
+ gpg_err_code_t _ms_err = make_space (&c, (n)); \
+ if (_ms_err) \
+ { \
+ err = _ms_err; \
+ *erroff = p - buffer; \
+ goto leave; \
+ } \
+ } while (0)
+
+ /* The STORE_LEN macro is used to store the length N at buffer P. */
+#define STORE_LEN(p,n) do { \
+ DATALEN ashort = (n); \
+ memcpy ( (p), &ashort, sizeof(ashort) ); \
+ (p) += sizeof (ashort); \
+ } while (0)
+
+ /* We assume that the internal representation takes less memory than
+ the provided one. However, we add space for one extra datalen so
+ that the code which does the ST_CLOSE can use MAKE_SPACE */
+ c.allocated = length + sizeof(DATALEN);
+ if (buffer && length && gcry_is_secure (buffer))
+ c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
+ else
+ c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
+ if (!c.sexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ *erroff = 0;
+ goto leave;
+ }
+ c.pos = c.sexp->d;
+
+ for (p = buffer, n = length; n; p++, n--)
+ {
+ if (tokenp && !hexfmt)
+ {
+ if (strchr (tokenchars, *p))
+ continue;
+ else
+ {
+ datalen = p - tokenp;
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, tokenp, datalen);
+ c.pos += datalen;
+ tokenp = NULL;
+ }
+ }
+
+ if (quoted)
+ {
+ if (quoted_esc)
+ {
+ switch (*p)
+ {
+ case 'b': case 't': case 'v': case 'n': case 'f':
+ case 'r': case '"': case '\'': case '\\':
+ quoted_esc = 0;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ if (!((n > 2)
+ && (p[1] >= '0') && (p[1] <= '7')
+ && (p[2] >= '0') && (p[2] <= '7')))
+ {
+ *erroff = p - buffer;
+ /* Invalid octal value. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ p += 2;
+ n -= 2;
+ quoted_esc = 0;
+ break;
+
+ case 'x':
+ if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
+ {
+ *erroff = p - buffer;
+ /* Invalid hex value. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ p += 2;
+ n -= 2;
+ quoted_esc = 0;
+ break;
+
+ case '\r':
+ /* ignore CR[,LF] */
+ if (n && (p[1] == '\n'))
+ {
+ p++;
+ n--;
+ }
+ quoted_esc = 0;
+ break;
+
+ case '\n':
+ /* ignore LF[,CR] */
+ if (n && (p[1] == '\r'))
+ {
+ p++;
+ n--;
+ }
+ quoted_esc = 0;
+ break;
+
+ default:
+ *erroff = p - buffer;
+ /* Invalid quoted string escape. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ }
+ else if (*p == '\\')
+ quoted_esc = 1;
+ else if (*p == '\"')
+ {
+ /* Keep it easy - we know that the unquoted string will
+ never be larger. */
+ unsigned char *save;
+ size_t len;
+
+ quoted++; /* Skip leading quote. */
+ MAKE_SPACE (p - quoted);
+ *c.pos++ = ST_DATA;
+ save = c.pos;
+ STORE_LEN (c.pos, 0); /* Will be fixed up later. */
+ len = unquote_string (quoted, p - quoted, c.pos);
+ c.pos += len;
+ STORE_LEN (save, len);
+ quoted = NULL;
+ }
+ }
+ else if (hexfmt)
+ {
+ if (isxdigit (*p))
+ hexcount++;
+ else if (*p == '#')
+ {
+ if ((hexcount & 1))
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
+ goto leave;
+ }
+
+ datalen = hexcount / 2;
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ for (hexfmt++; hexfmt < p; hexfmt++)
+ {
+ if (whitespacep (hexfmt))
+ continue;
+ *c.pos++ = hextobyte ((const unsigned char*)hexfmt);
+ hexfmt++;
+ }
+ hexfmt = NULL;
+ }
+ else if (!whitespacep (p))
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_HEX_CHAR;
+ goto leave;
+ }
+ }
+ else if (base64)
+ {
+ if (*p == '|')
+ base64 = NULL;
+ }
+ else if (digptr)
+ {
+ if (digitp (p))
+ ;
+ else if (*p == ':')
+ {
+ datalen = atoi (digptr); /* FIXME: check for overflow. */
+ digptr = NULL;
+ if (datalen > n - 1)
+ {
+ *erroff = p - buffer;
+ /* Buffer too short. */
+ err = GPG_ERR_SEXP_STRING_TOO_LONG;
+ goto leave;
+ }
+ /* Make a new list entry. */
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, p + 1, datalen);
+ c.pos += datalen;
+ n -= datalen;
+ p += datalen;
+ }
+ else if (*p == '\"')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ quoted = p;
+ quoted_esc = 0;
+ }
+ else if (*p == '#')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ hexfmt = p;
+ hexcount = 0;
+ }
+ else if (*p == '|')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ base64 = p;
+ }
+ else
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_INV_LEN_SPEC;
+ goto leave;
+ }
+ }
+ else if (percent)
+ {
+ if (*p == 'm' || *p == 'M')
+ {
+ /* Insert an MPI. */
+ gcry_mpi_t m;
+ size_t nm = 0;
+ int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG;
+
+ ARG_NEXT (m, gcry_mpi_t);
+
+ if (gcry_mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
+ {
+ void *mp;
+ unsigned int nbits;
+
+ mp = gcry_mpi_get_opaque (m, &nbits);
+ nm = (nbits+7)/8;
+ if (mp && nm)
+ {
+ MAKE_SPACE (nm);
+ if (!gcry_is_secure (c.sexp->d)
+ && gcry_mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = gcry_malloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ gcry_free (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, nm);
+ memcpy (c.pos, mp, nm);
+ c.pos += nm;
+ }
+ }
+ else
+ {
+ if (gcry_mpi_print (mpifmt, NULL, 0, &nm, m))
+ BUG ();
+
+ MAKE_SPACE (nm);
+ if (!gcry_is_secure (c.sexp->d)
+ && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = gcry_malloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ gcry_free (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, nm);
+ if (gcry_mpi_print (mpifmt, c.pos, nm, &nm, m))
+ BUG ();
+ c.pos += nm;
+ }
+ }
+ else if (*p == 's')
+ {
+ /* Insert an string. */
+ const char *astr;
+ size_t alen;
+
+ ARG_NEXT (astr, const char *);
+ alen = strlen (astr);
+
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, astr, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'b')
+ {
+ /* Insert a memory buffer. */
+ const char *astr;
+ int alen;
+
+ ARG_NEXT (alen, int);
+ ARG_NEXT (astr, const char *);
+
+ MAKE_SPACE (alen);
+ if (alen
+ && !gcry_is_secure (c.sexp->d)
+ && gcry_is_secure (astr))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = gcry_malloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ gcry_free (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, astr, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'd')
+ {
+ /* Insert an integer as string. */
+ int aint;
+ size_t alen;
+ char buf[35];
+
+ ARG_NEXT (aint, int);
+ sprintf (buf, "%d", aint);
+ alen = strlen (buf);
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, buf, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'u')
+ {
+ /* Insert an unsigned integer as string. */
+ unsigned int aint;
+ size_t alen;
+ char buf[35];
+
+ ARG_NEXT (aint, unsigned int);
+ sprintf (buf, "%u", aint);
+ alen = strlen (buf);
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, buf, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'S')
+ {
+ /* Insert a gcry_sexp_t. */
+ gcry_sexp_t asexp;
+ size_t alen, aoff;
+
+ ARG_NEXT (asexp, gcry_sexp_t);
+ alen = get_internal_buffer (asexp, &aoff);
+ if (alen)
+ {
+ MAKE_SPACE (alen);
+ memcpy (c.pos, asexp->d + aoff, alen);
+ c.pos += alen;
+ }
+ }
+ else
+ {
+ *erroff = p - buffer;
+ /* Invalid format specifier. */
+ err = GPG_ERR_SEXP_INV_LEN_SPEC;
+ goto leave;
+ }
+ percent = NULL;
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_OPEN;
+ level++;
+ }
+ else if (*p == ')')
+ {
+ /* Walk up. */
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_CLOSE;
+ level--;
+ }
+ else if (*p == '\"')
+ {
+ quoted = p;
+ quoted_esc = 0;
+ }
+ else if (*p == '#')
+ {
+ hexfmt = p;
+ hexcount = 0;
+ }
+ else if (*p == '|')
+ base64 = p;
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_NESTED_DH;
+ goto leave;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if (!disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ disphint = NULL;
+ }
+ else if (digitp (p))
+ {
+ if (*p == '0')
+ {
+ /* A length may not begin with zero. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_ZERO_PREFIX;
+ goto leave;
+ }
+ digptr = p;
+ }
+ else if (strchr (tokenchars, *p))
+ tokenp = p;
+ else if (whitespacep (p))
+ ;
+ else if (*p == '{')
+ {
+ /* fixme: handle rescanning: we can do this by saving our
+ current state and start over at p+1 -- Hmmm. At this
+ point here we are in a well defined state, so we don't
+ need to save it. Great. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ goto leave;
+ }
+ else if (strchr ("&\\", *p))
+ {
+ /* Reserved punctuation. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ goto leave;
+ }
+ else if (argflag && (*p == '%'))
+ percent = p;
+ else
+ {
+ /* Bad or unavailable. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_CHARACTER;
+ goto leave;
+ }
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_STOP;
+
+ if (level && !err)
+ err = GPG_ERR_SEXP_UNMATCHED_PAREN;
+
+ leave:
+ if (err)
+ {
+ /* Error -> deallocate. */
+ if (c.sexp)
+ {
+ /* Extra paranoid wipe on error. */
+ if (gcry_is_secure (c.sexp))
+ wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
+ gcry_free (c.sexp);
+ }
+ /* This might be expected by existing code... */
+ *retsexp = NULL;
+ }
+ else
+ *retsexp = normalize (c.sexp);
+
+ return gcry_error (err);
+#undef MAKE_SPACE
+#undef STORE_LEN
+}
+
+
+static gcry_error_t
+sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, ...)
+{
+ gcry_error_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, arg_list);
+ rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag,
+ arg_list, arg_ptr);
+ va_end (arg_ptr);
+
+ return rc;
+}
+
+
+gcry_error_t
+gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
+{
+ gcry_error_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+ NULL, arg_ptr);
+ va_end (arg_ptr);
+
+ return rc;
+}
+
+
+gcry_error_t
+_gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, va_list arg_ptr)
+{
+ return vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+ NULL, arg_ptr);
+}
+
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+ function arguments. */
+gcry_error_t
+gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list)
+{
+ return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
+}
+
+
+gcry_error_t
+gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length)
+{
+ return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
+}
+
+
+/* Figure out a suitable encoding for BUFFER of LENGTH.
+ Returns: 0 = Binary
+ 1 = String possible
+ 2 = Token possible
+*/
+static int
+suitable_encoding (const unsigned char *buffer, size_t length)
+{
+ const unsigned char *s;
+ int maybe_token = 1;
+
+ if (!length)
+ return 1;
+
+ for (s=buffer; length; s++, length--)
+ {
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
+ && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
+ return 0; /*binary*/
+ if ( maybe_token
+ && !alphap (s) && !digitp (s) && !strchr (TOKEN_SPECIALS, *s))
+ maybe_token = 0;
+ }
+ s = buffer;
+ if ( maybe_token && !digitp (s) )
+ return 2;
+ return 1;
+}
+
+
+static int
+convert_to_hex (const unsigned char *src, size_t len, char *dest)
+{
+ int i;
+
+ if (dest)
+ {
+ *dest++ = '#';
+ for (i=0; i < len; i++, dest += 2 )
+ sprintf (dest, "%02X", src[i]);
+ *dest++ = '#';
+ }
+ return len*2+2;
+}
+
+static int
+convert_to_string (const unsigned char *s, size_t len, char *dest)
+{
+ if (dest)
+ {
+ char *p = dest;
+ *p++ = '\"';
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b': *p++ = '\\'; *p++ = 'b'; break;
+ case '\t': *p++ = '\\'; *p++ = 't'; break;
+ case '\v': *p++ = '\\'; *p++ = 'v'; break;
+ case '\n': *p++ = '\\'; *p++ = 'n'; break;
+ case '\f': *p++ = '\\'; *p++ = 'f'; break;
+ case '\r': *p++ = '\\'; *p++ = 'r'; break;
+ case '\"': *p++ = '\\'; *p++ = '\"'; break;
+ case '\'': *p++ = '\\'; *p++ = '\''; break;
+ case '\\': *p++ = '\\'; *p++ = '\\'; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ {
+ sprintf (p, "\\x%02x", *s);
+ p += 4;
+ }
+ else
+ *p++ = *s;
+ }
+ }
+ *p++ = '\"';
+ return p - dest;
+ }
+ else
+ {
+ int count = 2;
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b':
+ case '\t':
+ case '\v':
+ case '\n':
+ case '\f':
+ case '\r':
+ case '\"':
+ case '\'':
+ case '\\': count += 2; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ count += 4;
+ else
+ count++;
+ }
+ }
+ return count;
+ }
+}
+
+
+
+static int
+convert_to_token (const unsigned char *src, size_t len, char *dest)
+{
+ if (dest)
+ memcpy (dest, src, len);
+ return len;
+}
+
+
+/****************
+ * Print SEXP to buffer using the MODE. Returns the length of the
+ * SEXP in buffer or 0 if the buffer is too short (We have at least an
+ * empty list consisting of 2 bytes). If a buffer of NULL is provided,
+ * the required length is returned.
+ */
+size_t
+gcry_sexp_sprint (const gcry_sexp_t list, int mode,
+ void *buffer, size_t maxlength )
+{
+ static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
+ const unsigned char *s;
+ char *d;
+ DATALEN n;
+ char numbuf[20];
+ size_t len = 0;
+ int i, indent = 0;
+
+ s = list? list->d : empty;
+ d = buffer;
+ while ( *s != ST_STOP )
+ {
+ switch ( *s )
+ {
+ case ST_OPEN:
+ s++;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ len++;
+ len += indent;
+ }
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ *d++ = '(';
+ }
+ indent++;
+ break;
+ case ST_CLOSE:
+ s++;
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = ')';
+ }
+ indent--;
+ if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
+ {
+ len++;
+ len += indent;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ }
+ break;
+ case ST_DATA:
+ s++;
+ memcpy ( &n, s, sizeof n ); s += sizeof n;
+ if (mode == GCRYSEXP_FMT_ADVANCED)
+ {
+ int type;
+ size_t nn;
+
+ switch ( (type=suitable_encoding (s, n)))
+ {
+ case 1: nn = convert_to_string (s, n, NULL); break;
+ case 2: nn = convert_to_token (s, n, NULL); break;
+ default: nn = convert_to_hex (s, n, NULL); break;
+ }
+ len += nn;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ switch (type)
+ {
+ case 1: convert_to_string (s, n, d); break;
+ case 2: convert_to_token (s, n, d); break;
+ default: convert_to_hex (s, n, d); break;
+ }
+ d += nn;
+ }
+ if (s[n] != ST_CLOSE)
+ {
+ len++;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = ' ';
+ }
+ }
+ }
+ else
+ {
+ sprintf (numbuf, "%u:", (unsigned int)n );
+ len += strlen (numbuf) + n;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ d = stpcpy ( d, numbuf );
+ memcpy ( d, s, n ); d += n;
+ }
+ }
+ s += n;
+ break;
+ default:
+ BUG ();
+ }
+ }
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ len++;
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = '\n';
+ }
+ }
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = 0; /* for convenience we make a C string */
+ }
+ else
+ len++; /* we need one byte more for this */
+
+ return len;
+}
+
+
+/* Scan a canonical encoded buffer with implicit length values and
+ return the actual length this S-expression uses. For a valid S-Exp
+ it should never return 0. If LENGTH is not zero, the maximum
+ length to scan is given - this can be used for syntax checks of
+ data passed from outside. errorcode and erroff may both be passed as
+ NULL. */
+size_t
+gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode)
+{
+ const unsigned char *p;
+ const unsigned char *disphint = NULL;
+ unsigned int datalen = 0;
+ size_t dummy_erroff;
+ gcry_error_t dummy_errcode;
+ size_t count = 0;
+ int level = 0;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+ if (!errcode)
+ errcode = &dummy_errcode;
+
+ *errcode = gcry_error (GPG_ERR_NO_ERROR);
+ *erroff = 0;
+ if (!buffer)
+ return 0;
+ if (*buffer != '(')
+ {
+ *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
+ return 0;
+ }
+
+ for (p=buffer; ; p++, count++ )
+ {
+ if (length && count >= length)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
+ return 0;
+ }
+
+ if (datalen)
+ {
+ if (*p == ':')
+ {
+ if (length && (count+datalen) >= length)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
+ return 0;
+ }
+ count += datalen;
+ p += datalen;
+ datalen = 0;
+ }
+ else if (digitp(p))
+ datalen = datalen*10 + atoi_1(p);
+ else
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
+ return 0;
+ }
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ level++;
+ }
+ else if (*p == ')')
+ { /* walk up */
+ if (!level)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
+ return 0;
+ }
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ if (!--level)
+ return ++count; /* ready */
+ }
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
+ return 0;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if ( !disphint )
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ disphint = NULL;
+ }
+ else if (digitp (p) )
+ {
+ if (*p == '0')
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
+ return 0;
+ }
+ datalen = atoi_1 (p);
+ }
+ else if (*p == '&' || *p == '\\')
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
+ return 0;
+ }
+ else
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);
+ return 0;
+ }
+ }
+}
diff --git a/grub-core/lib/libgcrypt/src/stdmem.c b/grub-core/lib/libgcrypt/src/stdmem.c
new file mode 100644
index 0000000..189da37
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/stdmem.c
@@ -0,0 +1,242 @@
+/* stdmem.c - private memory allocator
+ * Copyright (C) 1998, 2000, 2002, 2005, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Description of the layered memory management in Libgcrypt:
+ *
+ * [User]
+ * |
+ * |
+ * \ /
+ * global.c: [MM entrance points] -----> [user callbacks]
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * stdmem.c: [non-secure handlers] [secure handlers]
+ *
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * stdmem.c: [ memory guard ]
+ *
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * libc: [ MM functions ] secmem.c: [ secure MM functions]
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "stdmem.h"
+#include "secmem.h"
+
+
+
+#define MAGIC_NOR_BYTE 0x55
+#define MAGIC_SEC_BYTE 0xcc
+#define MAGIC_END_BYTE 0xaa
+
+#if SIZEOF_UNSIGNED_LONG == 8
+#define EXTRA_ALIGN 4
+#else
+#define EXTRA_ALIGN 0
+#endif
+
+
+static int use_m_guard = 0;
+
+/****************
+ * Warning: Never use this function after any of the functions
+ * here have been used.
+ */
+void
+_gcry_private_enable_m_guard (void)
+{
+ use_m_guard = 1;
+}
+
+
+/*
+ * Allocate memory of size n.
+ * Return NULL if we are out of memory.
+ */
+void *
+_gcry_private_malloc (size_t n)
+{
+ if (!n)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL; /* Allocating 0 bytes is undefined - we better return
+ an error to detect such coding errors. */
+ }
+
+ if (use_m_guard)
+ {
+ char *p;
+
+ if ( !(p = malloc (n + EXTRA_ALIGN+5)) )
+ return NULL;
+ ((byte*)p)[EXTRA_ALIGN+0] = n;
+ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
+ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
+ ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE;
+ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
+ return p+EXTRA_ALIGN+4;
+ }
+ else
+ {
+ return malloc( n );
+ }
+}
+
+
+/*
+ * Allocate memory of size N from the secure memory pool. Return NULL
+ * if we are out of memory.
+ */
+void *
+_gcry_private_malloc_secure (size_t n)
+{
+ if (!n)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL; /* Allocating 0 bytes is undefined - better return an
+ error to detect such coding errors. */
+ }
+
+ if (use_m_guard)
+ {
+ char *p;
+
+ if ( !(p = _gcry_secmem_malloc (n +EXTRA_ALIGN+ 5)) )
+ return NULL;
+ ((byte*)p)[EXTRA_ALIGN+0] = n;
+ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
+ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
+ ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE;
+ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
+ return p+EXTRA_ALIGN+4;
+ }
+ else
+ {
+ return _gcry_secmem_malloc( n );
+ }
+}
+
+
+/*
+ * Realloc and clear the old space
+ * Return NULL if there is not enough memory.
+ */
+void *
+_gcry_private_realloc ( void *a, size_t n )
+{
+ if (use_m_guard)
+ {
+ unsigned char *p = a;
+ char *b;
+ size_t len;
+
+ if (!a)
+ return _gcry_private_malloc(n);
+
+ _gcry_private_check_heap(p);
+ len = p[-4];
+ len |= p[-3] << 8;
+ len |= p[-2] << 16;
+ if( len >= n ) /* We don't shrink for now. */
+ return a;
+ if (p[-1] == MAGIC_SEC_BYTE)
+ b = _gcry_private_malloc_secure(n);
+ else
+ b = _gcry_private_malloc(n);
+ if (!b)
+ return NULL;
+ memcpy (b, a, len);
+ memset (b+len, 0, n-len);
+ _gcry_private_free (p);
+ return b;
+ }
+ else if ( _gcry_private_is_secure(a) )
+ {
+ return _gcry_secmem_realloc( a, n );
+ }
+ else
+ {
+ return realloc( a, n );
+ }
+}
+
+
+void
+_gcry_private_check_heap (const void *a)
+{
+ if (use_m_guard)
+ {
+ const byte *p = a;
+ size_t len;
+
+ if (!p)
+ return;
+
+ if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) )
+ _gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]);
+ len = p[-4];
+ len |= p[-3] << 8;
+ len |= p[-2] << 16;
+ if ( p[len] != MAGIC_END_BYTE )
+ _gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]);
+ }
+}
+
+
+/*
+ * Free a memory block allocated by this or the secmem module
+ */
+void
+_gcry_private_free (void *a)
+{
+ unsigned char *p = a;
+
+ if (!p)
+ return;
+ if (use_m_guard )
+ {
+ _gcry_private_check_heap(p);
+ if ( _gcry_private_is_secure(a) )
+ _gcry_secmem_free(p-EXTRA_ALIGN-4);
+ else
+ {
+ free(p-EXTRA_ALIGN-4);
+ }
+ }
+ else if ( _gcry_private_is_secure(a) )
+ _gcry_secmem_free(p);
+ else
+ free(p);
+}
diff --git a/grub-core/lib/libgcrypt/src/stdmem.h b/grub-core/lib/libgcrypt/src/stdmem.h
new file mode 100644
index 0000000..b476e7e
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/stdmem.h
@@ -0,0 +1,32 @@
+/* stdmem.h - internal definitions for stdmem
+ * Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef G10_STDMEM_H
+#define G10_STDMEM_H 1
+
+void _gcry_private_enable_m_guard(void);
+
+void *_gcry_private_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_private_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_private_realloc (void *a, size_t n);
+void _gcry_private_check_heap (const void *a);
+void _gcry_private_free (void *a);
+
+#endif /* G10_STDMEM_H */
diff --git a/grub-core/lib/libgcrypt/src/types.h b/grub-core/lib/libgcrypt/src/types.h
new file mode 100644
index 0000000..ee0a62b
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/types.h
@@ -0,0 +1,128 @@
+/* types.h - some common typedefs
+ * Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef GCRYPT_TYPES_H
+#define GCRYPT_TYPES_H
+
+
+/* The AC_CHECK_SIZEOF() in configure fails for some machines.
+ * we provide some fallback values here */
+#if !SIZEOF_UNSIGNED_SHORT
+#undef SIZEOF_UNSIGNED_SHORT
+#define SIZEOF_UNSIGNED_SHORT 2
+#endif
+#if !SIZEOF_UNSIGNED_INT
+#undef SIZEOF_UNSIGNED_INT
+#define SIZEOF_UNSIGNED_INT 4
+#endif
+#if !SIZEOF_UNSIGNED_LONG
+#undef SIZEOF_UNSIGNED_LONG
+#define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+
+#include <sys/types.h>
+
+
+#ifndef HAVE_BYTE_TYPEDEF
+#undef byte /* maybe there is a macro with this name */
+/* Windows typedefs byte in the rpc headers. Avoid warning about
+ double definition. */
+#if !(defined(_WIN32) && defined(cbNDRContext))
+ typedef unsigned char byte;
+#endif
+#define HAVE_BYTE_TYPEDEF
+#endif
+
+#ifndef HAVE_USHORT_TYPEDEF
+#undef ushort /* maybe there is a macro with this name */
+ typedef unsigned short ushort;
+#define HAVE_USHORT_TYPEDEF
+#endif
+
+#ifndef HAVE_ULONG_TYPEDEF
+#undef ulong /* maybe there is a macro with this name */
+ typedef unsigned long ulong;
+#define HAVE_ULONG_TYPEDEF
+#endif
+
+#ifndef HAVE_U16_TYPEDEF
+#undef u16 /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 2
+ typedef unsigned int u16;
+#elif SIZEOF_UNSIGNED_SHORT == 2
+ typedef unsigned short u16;
+#else
+#error no typedef for u16
+#endif
+#define HAVE_U16_TYPEDEF
+#endif
+
+#ifndef HAVE_U32_TYPEDEF
+#undef u32 /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int u32;
+#elif SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned long u32;
+#else
+#error no typedef for u32
+#endif
+#define HAVE_U32_TYPEDEF
+#endif
+
+/****************
+ * Warning: Some systems segfault when this u64 typedef and
+ * the dummy code in cipher/md.c is not available. Examples are
+ * Solaris and IRIX.
+ */
+#ifndef HAVE_U64_TYPEDEF
+#undef u64 /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 8
+ typedef unsigned int u64;
+#define U64_C(c) (c ## U)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_LONG == 8
+ typedef unsigned long u64;
+#define U64_C(c) (c ## UL)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_LONG_LONG == 8
+ typedef unsigned long long u64;
+#define U64_C(c) (c ## ULL)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UINT64_T == 8
+ typedef uint64_t u64;
+#define U64_C(c) (UINT64_C(c))
+#define HAVE_U64_TYPEDEF
+#endif
+#endif
+
+typedef union {
+ int a;
+ short b;
+ char c[1];
+ long d;
+#ifdef HAVE_U64_TYPEDEF
+ u64 e;
+#endif
+ float f;
+ double g;
+} PROPERLY_ALIGNED_TYPE;
+
+#endif /*GCRYPT_TYPES_H*/
diff --git a/grub-core/lib/libgcrypt/src/versioninfo.rc.in b/grub-core/lib/libgcrypt/src/versioninfo.rc.in
new file mode 100644
index 0000000..401851e
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/versioninfo.rc.in
@@ -0,0 +1,51 @@
+/* versioninfo.rc.in - for libgcrypt
+ * Copyright (C) 2005, 2006 g10 Code GmbH
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* This file is processed by configure to create versioninfo.rc */
+
+#line __LINE__ "versioninfo.rc.in"
+
+#include <afxres.h>
+
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @LIBGCRYPT_LT_CURRENT@,@LIBGCRYPT_LT_AGE@,@LIBGCRYPT_LT_REVISION@,@BUILD_REVISION@
+ PRODUCTVERSION @BUILD_FILEVERSION@
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x21L
+#else
+ FILEFLAGS 0x20L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).\0"
+ VALUE "CompanyName", "g10 Code GmbH\0"
+ VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0"
+ VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0"
+ VALUE "InternalName", "libgcrypt\0"
+ VALUE "LegalCopyright", "Copyright © 2011 Free Software Foundation, Inc.\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "libgcrypt.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "libgcrypt\0"
+ VALUE "ProductVersion", "@VERSION@\0"
+ VALUE "SpecialBuild", "@BUILD_TIMESTAMP@\0"
+ END
+ END
+END
diff --git a/grub-core/lib/libgcrypt/src/visibility.c b/grub-core/lib/libgcrypt/src/visibility.c
new file mode 100644
index 0000000..2d3edbc
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/visibility.c
@@ -0,0 +1,1146 @@
+/* visibility.c - Wrapper for all public functions.
+ * Copyright (C) 2007, 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdarg.h>
+
+#define _GCRY_INCLUDED_BY_VISIBILITY_C
+#include "g10lib.h"
+#include "cipher-proto.h"
+
+
+
+const char *
+gcry_strerror (gcry_error_t err)
+{
+ return _gcry_strerror (err);
+}
+
+const char *
+gcry_strsource (gcry_error_t err)
+{
+ return _gcry_strsource (err);
+}
+
+gcry_err_code_t
+gcry_err_code_from_errno (int err)
+{
+ return _gcry_err_code_from_errno (err);
+}
+
+int
+gcry_err_code_to_errno (gcry_err_code_t code)
+{
+ return _gcry_err_code_to_errno (code);
+}
+
+gcry_error_t
+gcry_err_make_from_errno (gcry_err_source_t source, int err)
+{
+ return _gcry_err_make_from_errno (source, err);
+}
+
+gcry_err_code_t
+gcry_error_from_errno (int err)
+{
+ return _gcry_error_from_errno (err);
+}
+
+const char *
+gcry_check_version (const char *req_version)
+{
+ return _gcry_check_version (req_version);
+}
+
+gcry_error_t
+gcry_control (enum gcry_ctl_cmds cmd, ...)
+{
+ gcry_error_t err;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, cmd);
+ err = _gcry_vcontrol (cmd, arg_ptr);
+ va_end(arg_ptr);
+ return err;
+}
+
+gcry_error_t
+gcry_sexp_new (gcry_sexp_t *retsexp,
+ const void *buffer, size_t length,
+ int autodetect)
+{
+ return _gcry_sexp_new (retsexp, buffer, length, autodetect);
+}
+
+gcry_error_t
+gcry_sexp_create (gcry_sexp_t *retsexp,
+ void *buffer, size_t length,
+ int autodetect, void (*freefnc) (void *))
+{
+ return _gcry_sexp_create (retsexp, buffer, length,
+ autodetect, freefnc);
+}
+
+gcry_error_t
+gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length)
+{
+ return _gcry_sexp_sscan (retsexp, erroff, buffer, length);
+}
+
+gcry_error_t
+gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, ...)
+{
+ gcry_error_t err;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ err = _gcry_sexp_vbuild (retsexp, erroff, format, arg_ptr);
+ va_end (arg_ptr);
+ return err;
+}
+
+gcry_error_t
+gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list)
+{
+ return _gcry_sexp_build_array (retsexp, erroff, format, arg_list);
+}
+
+void
+gcry_sexp_release (gcry_sexp_t sexp)
+{
+ _gcry_sexp_release (sexp);
+}
+
+size_t
+gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode)
+{
+ return _gcry_sexp_canon_len (buffer, length, erroff, errcode);
+}
+
+size_t
+gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, size_t maxlength)
+{
+ return _gcry_sexp_sprint (sexp, mode, buffer, maxlength);
+}
+
+void
+gcry_sexp_dump (const gcry_sexp_t a)
+{
+ _gcry_sexp_dump (a);
+}
+
+gcry_sexp_t
+gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b)
+{
+ return _gcry_sexp_cons (a, b);
+}
+
+gcry_sexp_t
+gcry_sexp_alist (const gcry_sexp_t *array)
+{
+ return _gcry_sexp_alist (array);
+}
+
+gcry_sexp_t
+gcry_sexp_vlist (const gcry_sexp_t a, ...)
+{
+ /* This is not yet implemented in sexp.c. */
+ (void)a;
+ BUG ();
+ return NULL;
+}
+
+gcry_sexp_t
+gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n)
+{
+ return _gcry_sexp_append (a, n);
+}
+
+gcry_sexp_t
+gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n)
+{
+ return _gcry_sexp_prepend (a, n);
+}
+
+
+gcry_sexp_t
+gcry_sexp_find_token (gcry_sexp_t list, const char *tok, size_t toklen)
+{
+ return _gcry_sexp_find_token (list, tok, toklen);
+}
+
+int
+gcry_sexp_length (const gcry_sexp_t list)
+{
+ return _gcry_sexp_length (list);
+}
+
+gcry_sexp_t
+gcry_sexp_nth (const gcry_sexp_t list, int number)
+{
+ return _gcry_sexp_nth (list, number);
+}
+
+gcry_sexp_t
+gcry_sexp_car (const gcry_sexp_t list)
+{
+ return _gcry_sexp_car (list);
+}
+
+gcry_sexp_t
+gcry_sexp_cdr (const gcry_sexp_t list)
+{
+ return _gcry_sexp_cdr (list);
+}
+
+gcry_sexp_t
+gcry_sexp_cadr (const gcry_sexp_t list)
+{
+ return _gcry_sexp_cadr (list);
+}
+
+const char *
+gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
+{
+ return _gcry_sexp_nth_data (list, number, datalen);
+}
+
+char *
+gcry_sexp_nth_string (gcry_sexp_t list, int number)
+{
+ return _gcry_sexp_nth_string (list, number);
+}
+
+gcry_mpi_t
+gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt)
+{
+ return _gcry_sexp_nth_mpi (list, number, mpifmt);
+}
+
+gcry_mpi_t
+gcry_mpi_new (unsigned int nbits)
+{
+ return _gcry_mpi_new (nbits);
+}
+
+gcry_mpi_t
+gcry_mpi_snew (unsigned int nbits)
+{
+ return _gcry_mpi_snew (nbits);
+}
+
+void
+gcry_mpi_release (gcry_mpi_t a)
+{
+ _gcry_mpi_release (a);
+}
+
+gcry_mpi_t
+gcry_mpi_copy (const gcry_mpi_t a)
+{
+ return _gcry_mpi_copy (a);
+}
+
+gcry_mpi_t
+gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u)
+{
+ return _gcry_mpi_set (w, u);
+}
+
+gcry_mpi_t
+gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
+{
+ return _gcry_mpi_set_ui (w, u);
+}
+
+void
+gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
+{
+ _gcry_mpi_swap (a, b);
+}
+
+int
+gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v)
+{
+ return _gcry_mpi_cmp (u, v);
+}
+
+int
+gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v)
+{
+ return _gcry_mpi_cmp_ui (u, v);
+}
+
+gcry_error_t
+gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+ const void *buffer, size_t buflen,
+ size_t *nscanned)
+{
+ return _gcry_mpi_scan (ret_mpi, format, buffer, buflen, nscanned);
+}
+
+gcry_error_t
+gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten,
+ const gcry_mpi_t a)
+{
+ return _gcry_mpi_print (format, buffer, buflen, nwritten, a);
+}
+
+gcry_error_t
+gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ const gcry_mpi_t a)
+{
+ return _gcry_mpi_aprint (format, buffer, nwritten, a);
+}
+
+void
+gcry_mpi_dump (const gcry_mpi_t a)
+{
+ _gcry_mpi_dump (a);
+}
+
+void
+gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_add (w, u, v);
+}
+
+void
+gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v)
+{
+ _gcry_mpi_add_ui (w, u, v);
+}
+
+void
+gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_addm (w, u, v, m);
+}
+
+void
+gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_sub (w, u, v);
+}
+
+void
+gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ _gcry_mpi_sub_ui (w, u, v);
+}
+
+void
+gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_subm (w, u, v, m);
+}
+
+void
+gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_mul (w, u, v);
+}
+
+void
+gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ _gcry_mpi_mul_ui (w, u, v);
+}
+
+void
+gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_mulm (w, u, v, m);
+}
+
+void
+gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
+{
+ _gcry_mpi_mul_2exp (w, u, cnt);
+}
+
+void
+gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+ gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
+{
+ _gcry_mpi_div (q, r, dividend, divisor, round);
+}
+
+void
+gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor)
+{
+ _gcry_mpi_mod (r, dividend, divisor);
+}
+
+void
+gcry_mpi_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
+ const gcry_mpi_t m)
+{
+ _gcry_mpi_powm (w, b, e, m);
+}
+
+int
+gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b)
+{
+ return _gcry_mpi_gcd (g, a, b);
+}
+
+int
+gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m)
+{
+ return _gcry_mpi_invm (x, a, m);
+}
+
+
+unsigned int
+gcry_mpi_get_nbits (gcry_mpi_t a)
+{
+ return _gcry_mpi_get_nbits (a);
+}
+
+int
+gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n)
+{
+ return _gcry_mpi_test_bit (a, n);
+}
+
+void
+gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_set_bit (a, n);
+}
+
+void
+gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_clear_bit (a, n);
+}
+
+void
+gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_set_highbit (a, n);
+}
+
+void
+gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_clear_highbit (a, n);
+}
+
+void
+gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_rshift (x, a, n);
+}
+
+void
+gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_lshift (x, a, n);
+}
+
+gcry_mpi_t
+gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
+{
+ return _gcry_mpi_set_opaque (a, p, nbits);
+}
+
+void *
+gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
+{
+ return _gcry_mpi_get_opaque (a, nbits);
+}
+
+void
+gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ _gcry_mpi_set_flag (a, flag);
+}
+
+void
+gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ _gcry_mpi_clear_flag (a, flag);
+}
+
+int
+gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ return _gcry_mpi_get_flag (a, flag);
+}
+
+gcry_error_t
+gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags)
+{
+ if (!fips_is_operational ())
+ {
+ *handle = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+
+ return _gcry_cipher_open (handle, algo, mode, flags);
+}
+
+void
+gcry_cipher_close (gcry_cipher_hd_t h)
+{
+ _gcry_cipher_close (h);
+}
+
+gcry_error_t
+gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_setkey (hd, key, keylen);
+}
+
+gcry_error_t
+gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_setiv (hd, iv, ivlen);
+}
+
+gpg_error_t
+gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_setctr (hd, ctr, ctrlen);
+}
+
+
+gcry_error_t
+gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_ctl (h, cmd, buffer, buflen);
+}
+
+gcry_error_t
+gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes)
+{
+ return _gcry_cipher_info (h, what, buffer, nbytes);
+}
+
+gcry_error_t
+gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_algo_info (algo, what, buffer, nbytes);
+}
+
+const char *
+gcry_cipher_algo_name (int algorithm)
+{
+ return _gcry_cipher_algo_name (algorithm);
+}
+
+int
+gcry_cipher_map_name (const char *name)
+{
+ return _gcry_cipher_map_name (name);
+}
+
+int
+gcry_cipher_mode_from_oid (const char *string)
+{
+ return _gcry_cipher_mode_from_oid (string);
+}
+
+gcry_error_t
+gcry_cipher_encrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ if (!fips_is_operational ())
+ {
+ /* Make sure that the plaintext will never make it to OUT. */
+ if (out)
+ memset (out, 0x42, outsize);
+ return gpg_error (fips_not_operational ());
+ }
+
+ return _gcry_cipher_encrypt (h, out, outsize, in, inlen);
+}
+
+gcry_error_t
+gcry_cipher_decrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_decrypt (h, out, outsize, in, inlen);
+}
+
+size_t
+gcry_cipher_get_algo_keylen (int algo)
+{
+ return _gcry_cipher_get_algo_keylen (algo);
+}
+
+size_t
+gcry_cipher_get_algo_blklen (int algo)
+{
+ return _gcry_cipher_get_algo_blklen (algo);
+}
+
+gcry_error_t
+gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_pk_encrypt (result, data, pkey);
+}
+
+gcry_error_t
+gcry_pk_decrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_pk_decrypt (result, data, skey);
+}
+
+gcry_error_t
+gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_pk_sign (result, data, skey);
+}
+
+gcry_error_t
+gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_pk_verify (sigval, data, pkey);
+}
+
+gcry_error_t
+gcry_pk_testkey (gcry_sexp_t key)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_pk_testkey (key);
+}
+
+gcry_error_t
+gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
+{
+ if (!fips_is_operational ())
+ {
+ *r_key = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_pk_genkey (r_key, s_parms);
+}
+
+gcry_error_t
+gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
+{
+ return _gcry_pk_ctl (cmd, buffer, buflen);
+}
+
+gcry_error_t
+gcry_pk_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_pk_algo_info (algo, what, buffer, nbytes);
+}
+
+const char *
+gcry_pk_algo_name (int algorithm)
+{
+ return _gcry_pk_algo_name (algorithm);
+}
+
+int
+gcry_pk_map_name (const char *name)
+{
+ return _gcry_pk_map_name (name);
+}
+
+unsigned int
+gcry_pk_get_nbits (gcry_sexp_t key)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return 0;
+ }
+
+ return _gcry_pk_get_nbits (key);
+}
+
+unsigned char *
+gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_keygrip (key, array);
+}
+
+const char *
+gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_curve (key, iterator, r_nbits);
+}
+
+gcry_sexp_t
+gcry_pk_get_param (int algo, const char *name)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_param (algo, name);
+}
+
+gcry_error_t
+gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
+{
+ if (!fips_is_operational ())
+ {
+ *h = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+
+ return _gcry_md_open (h, algo, flags);
+}
+
+void
+gcry_md_close (gcry_md_hd_t hd)
+{
+ _gcry_md_close (hd);
+}
+
+gcry_error_t
+gcry_md_enable (gcry_md_hd_t hd, int algo)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_md_enable (hd, algo);
+}
+
+gcry_error_t
+gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd)
+{
+ if (!fips_is_operational ())
+ {
+ *bhd = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_md_copy (bhd, ahd);
+}
+
+void
+gcry_md_reset (gcry_md_hd_t hd)
+{
+ _gcry_md_reset (hd);
+}
+
+gcry_error_t
+gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_md_ctl (hd, cmd, buffer, buflen);
+}
+
+void
+gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return;
+ }
+ _gcry_md_write (hd, buffer, length);
+}
+
+unsigned char *
+gcry_md_read (gcry_md_hd_t hd, int algo)
+{
+ return _gcry_md_read (hd, algo);
+}
+
+void
+gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_error ("called in non-operational state");
+ }
+ _gcry_md_hash_buffer (algo, digest, buffer, length);
+}
+
+int
+gcry_md_get_algo (gcry_md_hd_t hd)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_error ("used in non-operational state");
+ return 0;
+ }
+ return _gcry_md_get_algo (hd);
+}
+
+unsigned int
+gcry_md_get_algo_dlen (int algo)
+{
+ return _gcry_md_get_algo_dlen (algo);
+}
+
+int
+gcry_md_is_enabled (gcry_md_hd_t a, int algo)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return 0;
+ }
+
+ return _gcry_md_is_enabled (a, algo);
+}
+
+int
+gcry_md_is_secure (gcry_md_hd_t a)
+{
+ return _gcry_md_is_secure (a);
+}
+
+gcry_error_t
+gcry_md_info (gcry_md_hd_t h, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_md_info (h, what, buffer, nbytes);
+}
+
+gcry_error_t
+gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ return _gcry_md_algo_info (algo, what, buffer, nbytes);
+}
+
+const char *
+gcry_md_algo_name (int algo)
+{
+ return _gcry_md_algo_name (algo);
+}
+
+int
+gcry_md_map_name (const char* name)
+{
+ return _gcry_md_map_name (name);
+}
+
+gcry_error_t
+gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_md_setkey (hd, key, keylen);
+}
+
+void
+gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
+{
+ _gcry_md_debug (hd, suffix);
+}
+
+gpg_error_t
+gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ return _gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+}
+
+void
+gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+ _gcry_randomize (buffer, length, level);
+}
+
+gcry_error_t
+gcry_random_add_bytes (const void *buffer, size_t length, int quality)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_random_add_bytes (buffer, length, quality);
+}
+
+void *
+gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+
+ return _gcry_random_bytes (nbytes,level);
+}
+
+void *
+gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+
+ return _gcry_random_bytes_secure (nbytes, level);
+}
+
+void
+gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level)
+{
+ _gcry_mpi_randomize (w, nbits, level);
+}
+
+void
+gcry_create_nonce (void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+ _gcry_create_nonce (buffer, length);
+}
+
+gcry_error_t
+gcry_prime_generate (gcry_mpi_t *prime,
+ unsigned int prime_bits,
+ unsigned int factor_bits,
+ gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func,
+ void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags)
+{
+ return _gcry_prime_generate (prime, prime_bits, factor_bits, factors,
+ cb_func, cb_arg, random_level, flags);
+}
+
+gcry_error_t
+gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime, gcry_mpi_t *factors,
+ gcry_mpi_t start_g)
+{
+ return _gcry_prime_group_generator (r_g, prime, factors, start_g);
+}
+
+void
+gcry_prime_release_factors (gcry_mpi_t *factors)
+{
+ _gcry_prime_release_factors (factors);
+}
+
+gcry_error_t
+gcry_prime_check (gcry_mpi_t x, unsigned int flags)
+{
+ return _gcry_prime_check (x, flags);
+}
+
+void
+gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data)
+{
+ _gcry_set_progress_handler (cb, cb_data);
+}
+
+void
+gcry_set_allocation_handler (gcry_handler_alloc_t func_alloc,
+ gcry_handler_alloc_t func_alloc_secure,
+ gcry_handler_secure_check_t func_secure_check,
+ gcry_handler_realloc_t func_realloc,
+ gcry_handler_free_t func_free)
+{
+ _gcry_set_allocation_handler (func_alloc, func_alloc_secure,
+ func_secure_check, func_realloc, func_free);
+}
+
+void
+gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque)
+{
+ _gcry_set_outofcore_handler (h, opaque);
+}
+
+void
+gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque)
+{
+ _gcry_set_fatalerror_handler (fnc, opaque);
+}
+
+void
+gcry_set_log_handler (gcry_handler_log_t f, void *opaque)
+{
+ _gcry_set_log_handler (f, opaque);
+}
+
+void
+gcry_set_gettext_handler (const char *(*f)(const char*))
+{
+ _gcry_set_gettext_handler (f);
+}
+
+void *
+gcry_malloc (size_t n)
+{
+ return _gcry_malloc (n);
+}
+
+void *
+gcry_calloc (size_t n, size_t m)
+{
+ return _gcry_calloc (n, m);
+}
+
+void *
+gcry_malloc_secure (size_t n)
+{
+ return _gcry_malloc_secure (n);
+}
+
+void *
+gcry_calloc_secure (size_t n, size_t m)
+{
+ return _gcry_calloc_secure (n,m);
+}
+
+void *
+gcry_realloc (void *a, size_t n)
+{
+ return _gcry_realloc (a, n);
+}
+
+char *
+gcry_strdup (const char *string)
+{
+ return _gcry_strdup (string);
+}
+
+void *
+gcry_xmalloc (size_t n)
+{
+ return _gcry_xmalloc (n);
+}
+
+void *
+gcry_xcalloc (size_t n, size_t m)
+{
+ return _gcry_xcalloc (n, m);
+}
+
+void *
+gcry_xmalloc_secure (size_t n)
+{
+ return _gcry_xmalloc_secure (n);
+}
+
+void *
+gcry_xcalloc_secure (size_t n, size_t m)
+{
+ return _gcry_xcalloc_secure (n, m);
+}
+
+void *
+gcry_xrealloc (void *a, size_t n)
+{
+ return _gcry_xrealloc (a, n);
+}
+
+char *
+gcry_xstrdup (const char *a)
+{
+ return _gcry_xstrdup (a);
+}
+
+void
+gcry_free (void *a)
+{
+ _gcry_free (a);
+}
+
+int
+gcry_is_secure (const void *a)
+{
+ return _gcry_is_secure (a);
+}
diff --git a/grub-core/lib/libgcrypt/src/visibility.h b/grub-core/lib/libgcrypt/src/visibility.h
new file mode 100644
index 0000000..4606a20
--- /dev/null
+++ b/grub-core/lib/libgcrypt/src/visibility.h
@@ -0,0 +1,565 @@
+/* visibility.h - Set visibility attribute
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_VISIBILITY_H
+#define GCRY_VISIBILITY_H
+
+/* Redefine all public symbols with an underscore unless we already
+ use the underscore prefixed version internally. */
+#define gcry_check_version _gcry_check_version
+#define gcry_control _gcry_control
+
+#define gcry_set_allocation_handler _gcry_set_allocation_handler
+#define gcry_set_fatalerror_handler _gcry_set_fatalerror_handler
+#define gcry_set_gettext_handler _gcry_set_gettext_handler
+#define gcry_set_log_handler _gcry_set_log_handler
+#define gcry_set_outofcore_handler _gcry_set_outofcore_handler
+#define gcry_set_progress_handler _gcry_set_progress_handler
+#define gcry_err_code_from_errno _gcry_err_code_from_errno
+#define gcry_err_code_to_errno _gcry_err_code_to_errno
+#define gcry_err_make_from_errno _gcry_err_make_from_errno
+#define gcry_error_from_errno _gcry_error_from_errno
+#define gcry_strerror _gcry_strerror
+#define gcry_strsource _gcry_strsource
+
+#define gcry_free _gcry_free
+#define gcry_malloc _gcry_malloc
+#define gcry_malloc_secure _gcry_malloc_secure
+#define gcry_calloc _gcry_calloc
+#define gcry_calloc_secure _gcry_calloc_secure
+#define gcry_realloc _gcry_realloc
+#define gcry_strdup _gcry_strdup
+#define gcry_is_secure _gcry_is_secure
+#define gcry_xcalloc _gcry_xcalloc
+#define gcry_xcalloc_secure _gcry_xcalloc_secure
+#define gcry_xmalloc _gcry_xmalloc
+#define gcry_xmalloc_secure _gcry_xmalloc_secure
+#define gcry_xrealloc _gcry_xrealloc
+#define gcry_xstrdup _gcry_xstrdup
+
+#define gcry_md_algo_info _gcry_md_algo_info
+#define gcry_md_algo_name _gcry_md_algo_name
+#define gcry_md_close _gcry_md_close
+#define gcry_md_copy _gcry_md_copy
+#define gcry_md_ctl _gcry_md_ctl
+#define gcry_md_enable _gcry_md_enable
+#define gcry_md_get _gcry_md_get
+#define gcry_md_get_algo _gcry_md_get_algo
+#define gcry_md_get_algo_dlen _gcry_md_get_algo_dlen
+#define gcry_md_hash_buffer _gcry_md_hash_buffer
+#define gcry_md_info _gcry_md_info
+#define gcry_md_is_enabled _gcry_md_is_enabled
+#define gcry_md_is_secure _gcry_md_is_secure
+#define gcry_md_map_name _gcry_md_map_name
+#define gcry_md_open _gcry_md_open
+#define gcry_md_read _gcry_md_read
+#define gcry_md_reset _gcry_md_reset
+#define gcry_md_setkey _gcry_md_setkey
+#define gcry_md_write _gcry_md_write
+#define gcry_md_debug _gcry_md_debug
+
+#define gcry_cipher_algo_info _gcry_cipher_algo_info
+#define gcry_cipher_algo_name _gcry_cipher_algo_name
+#define gcry_cipher_close _gcry_cipher_close
+#define gcry_cipher_setkey _gcry_cipher_setkey
+#define gcry_cipher_setiv _gcry_cipher_setiv
+#define gcry_cipher_setctr _gcry_cipher_setctr
+#define gcry_cipher_ctl _gcry_cipher_ctl
+#define gcry_cipher_decrypt _gcry_cipher_decrypt
+#define gcry_cipher_encrypt _gcry_cipher_encrypt
+#define gcry_cipher_get_algo_blklen _gcry_cipher_get_algo_blklen
+#define gcry_cipher_get_algo_keylen _gcry_cipher_get_algo_keylen
+#define gcry_cipher_info _gcry_cipher_info
+#define gcry_cipher_map_name _gcry_cipher_map_name
+#define gcry_cipher_mode_from_oid _gcry_cipher_mode_from_oid
+#define gcry_cipher_open _gcry_cipher_open
+
+#define gcry_pk_algo_info _gcry_pk_algo_info
+#define gcry_pk_algo_name _gcry_pk_algo_name
+#define gcry_pk_ctl _gcry_pk_ctl
+#define gcry_pk_decrypt _gcry_pk_decrypt
+#define gcry_pk_encrypt _gcry_pk_encrypt
+#define gcry_pk_genkey _gcry_pk_genkey
+#define gcry_pk_get_keygrip _gcry_pk_get_keygrip
+#define gcry_pk_get_curve _gcry_pk_get_curve
+#define gcry_pk_get_param _gcry_pk_get_param
+#define gcry_pk_get_nbits _gcry_pk_get_nbits
+#define gcry_pk_map_name _gcry_pk_map_name
+#define gcry_pk_sign _gcry_pk_sign
+#define gcry_pk_testkey _gcry_pk_testkey
+#define gcry_pk_verify _gcry_pk_verify
+
+#define gcry_kdf_derive _gcry_kdf_derive
+
+#define gcry_prime_check _gcry_prime_check
+#define gcry_prime_generate _gcry_prime_generate
+#define gcry_prime_group_generator _gcry_prime_group_generator
+#define gcry_prime_release_factors _gcry_prime_release_factors
+
+#define gcry_random_add_bytes _gcry_random_add_bytes
+#define gcry_random_bytes _gcry_random_bytes
+#define gcry_random_bytes_secure _gcry_random_bytes_secure
+#define gcry_randomize _gcry_randomize
+#define gcry_create_nonce _gcry_create_nonce
+
+#define gcry_sexp_alist _gcry_sexp_alist
+#define gcry_sexp_append _gcry_sexp_append
+#define gcry_sexp_build _gcry_sexp_build
+#define gcry_sexp_build_array _gcry_sexp_build_array
+#define gcry_sexp_cadr _gcry_sexp_cadr
+#define gcry_sexp_canon_len _gcry_sexp_canon_len
+#define gcry_sexp_car _gcry_sexp_car
+#define gcry_sexp_cdr _gcry_sexp_cdr
+#define gcry_sexp_cons _gcry_sexp_cons
+#define gcry_sexp_create _gcry_sexp_create
+#define gcry_sexp_dump _gcry_sexp_dump
+#define gcry_sexp_find_token _gcry_sexp_find_token
+#define gcry_sexp_length _gcry_sexp_length
+#define gcry_sexp_new _gcry_sexp_new
+#define gcry_sexp_nth _gcry_sexp_nth
+#define gcry_sexp_nth_data _gcry_sexp_nth_data
+#define gcry_sexp_nth_mpi _gcry_sexp_nth_mpi
+#define gcry_sexp_prepend _gcry_sexp_prepend
+#define gcry_sexp_release _gcry_sexp_release
+#define gcry_sexp_sprint _gcry_sexp_sprint
+#define gcry_sexp_sscan _gcry_sexp_sscan
+#define gcry_sexp_vlist _gcry_sexp_vlist
+#define gcry_sexp_nth_string _gcry_sexp_nth_string
+
+#define gcry_mpi_add _gcry_mpi_add
+#define gcry_mpi_add_ui _gcry_mpi_add_ui
+#define gcry_mpi_addm _gcry_mpi_addm
+#define gcry_mpi_aprint _gcry_mpi_aprint
+#define gcry_mpi_clear_bit _gcry_mpi_clear_bit
+#define gcry_mpi_clear_flag _gcry_mpi_clear_flag
+#define gcry_mpi_clear_highbit _gcry_mpi_clear_highbit
+#define gcry_mpi_cmp _gcry_mpi_cmp
+#define gcry_mpi_cmp_ui _gcry_mpi_cmp_ui
+#define gcry_mpi_copy _gcry_mpi_copy
+#define gcry_mpi_div _gcry_mpi_div
+#define gcry_mpi_dump _gcry_mpi_dump
+#define gcry_mpi_gcd _gcry_mpi_gcd
+#define gcry_mpi_get_flag _gcry_mpi_get_flag
+#define gcry_mpi_get_nbits _gcry_mpi_get_nbits
+#define gcry_mpi_get_opaque _gcry_mpi_get_opaque
+#define gcry_mpi_invm _gcry_mpi_invm
+#define gcry_mpi_mod _gcry_mpi_mod
+#define gcry_mpi_mul _gcry_mpi_mul
+#define gcry_mpi_mul_2exp _gcry_mpi_mul_2exp
+#define gcry_mpi_mul_ui _gcry_mpi_mul_ui
+#define gcry_mpi_mulm _gcry_mpi_mulm
+#define gcry_mpi_new _gcry_mpi_new
+#define gcry_mpi_powm _gcry_mpi_powm
+#define gcry_mpi_print _gcry_mpi_print
+#define gcry_mpi_randomize _gcry_mpi_randomize
+#define gcry_mpi_release _gcry_mpi_release
+#define gcry_mpi_rshift _gcry_mpi_rshift
+#define gcry_mpi_lshift _gcry_mpi_lshift
+#define gcry_mpi_scan _gcry_mpi_scan
+#define gcry_mpi_set _gcry_mpi_set
+#define gcry_mpi_set_bit _gcry_mpi_set_bit
+#define gcry_mpi_set_flag _gcry_mpi_set_flag
+#define gcry_mpi_set_highbit _gcry_mpi_set_highbit
+#define gcry_mpi_set_opaque _gcry_mpi_set_opaque
+#define gcry_mpi_set_ui _gcry_mpi_set_ui
+#define gcry_mpi_snew _gcry_mpi_snew
+#define gcry_mpi_sub _gcry_mpi_sub
+#define gcry_mpi_sub_ui _gcry_mpi_sub_ui
+#define gcry_mpi_subm _gcry_mpi_subm
+#define gcry_mpi_swap _gcry_mpi_swap
+#define gcry_mpi_test_bit _gcry_mpi_test_bit
+
+
+/* Include the main header here so that public symbols are mapped to
+ the internal underscored ones. */
+#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C
+ /* We need to redeclare the deprecated functions without the
+ deprecated attribute. */
+# define GCRYPT_NO_DEPRECATED
+# include "gcrypt.h"
+ /* None in this version. */
+#else
+# include "gcrypt.h"
+#endif
+#include "gcrypt-module.h"
+
+/* Prototypes of functions exported but not ready for use. */
+gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
+ unsigned char *buffer, int buflen);
+
+
+/* Our use of the ELF visibility feature works by passing
+ -fvisibiliy=hidden on the command line and by explicitly marking
+ all exported functions as visible.
+
+ NOTE: When adding new functions, please make sure to add them to
+ libgcrypt.vers and libgcrypt.def as well. */
+
+#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C
+
+/* A macro to flag a function as visible. Note that we take the
+ definition from the mapped name. */
+#ifdef GCRY_USE_VISIBILITY
+# define MARK_VISIBLE(name) \
+ extern __typeof__ (_##name) name __attribute__ ((visibility("default")));
+# define MARK_VISIBLEX(name) \
+ extern __typeof__ (name) name __attribute__ ((visibility("default")));
+#else
+# define MARK_VISIBLE(name) /* */
+# define MARK_VISIBLEX(name) /* */
+#endif
+
+
+/* First undef all redefined symbols so that we set the attribute on
+ the correct version name. */
+#undef gcry_check_version
+#undef gcry_control
+
+#undef gcry_set_allocation_handler
+#undef gcry_set_fatalerror_handler
+#undef gcry_set_gettext_handler
+#undef gcry_set_log_handler
+#undef gcry_set_outofcore_handler
+#undef gcry_set_progress_handler
+#undef gcry_err_code_from_errno
+#undef gcry_err_code_to_errno
+#undef gcry_err_make_from_errno
+#undef gcry_error_from_errno
+#undef gcry_strerror
+#undef gcry_strsource
+
+#undef gcry_free
+#undef gcry_malloc
+#undef gcry_malloc_secure
+#undef gcry_calloc
+#undef gcry_calloc_secure
+#undef gcry_realloc
+#undef gcry_strdup
+#undef gcry_is_secure
+#undef gcry_xcalloc
+#undef gcry_xcalloc_secure
+#undef gcry_xmalloc
+#undef gcry_xmalloc_secure
+#undef gcry_xrealloc
+#undef gcry_xstrdup
+
+#undef gcry_md_algo_info
+#undef gcry_md_algo_name
+#undef gcry_md_close
+#undef gcry_md_copy
+#undef gcry_md_ctl
+#undef gcry_md_enable
+#undef gcry_md_get
+#undef gcry_md_get_algo
+#undef gcry_md_get_algo_dlen
+#undef gcry_md_hash_buffer
+#undef gcry_md_info
+#undef gcry_md_is_enabled
+#undef gcry_md_is_secure
+#undef gcry_md_map_name
+#undef gcry_md_open
+#undef gcry_md_read
+#undef gcry_md_reset
+#undef gcry_md_setkey
+#undef gcry_md_write
+#undef gcry_md_debug
+
+#undef gcry_cipher_algo_info
+#undef gcry_cipher_algo_name
+#undef gcry_cipher_close
+#undef gcry_cipher_setkey
+#undef gcry_cipher_setiv
+#undef gcry_cipher_setctr
+#undef gcry_cipher_ctl
+#undef gcry_cipher_decrypt
+#undef gcry_cipher_encrypt
+#undef gcry_cipher_get_algo_blklen
+#undef gcry_cipher_get_algo_keylen
+#undef gcry_cipher_info
+#undef gcry_cipher_map_name
+#undef gcry_cipher_mode_from_oid
+#undef gcry_cipher_open
+
+#undef gcry_pk_algo_info
+#undef gcry_pk_algo_name
+#undef gcry_pk_ctl
+#undef gcry_pk_decrypt
+#undef gcry_pk_encrypt
+#undef gcry_pk_genkey
+#undef gcry_pk_get_keygrip
+#undef gcry_pk_get_curve
+#undef gcry_pk_get_param
+#undef gcry_pk_get_nbits
+#undef gcry_pk_map_name
+#undef gcry_pk_sign
+#undef gcry_pk_testkey
+#undef gcry_pk_verify
+
+#undef gcry_kdf_derive
+
+#undef gcry_prime_check
+#undef gcry_prime_generate
+#undef gcry_prime_group_generator
+#undef gcry_prime_release_factors
+
+#undef gcry_random_add_bytes
+#undef gcry_random_bytes
+#undef gcry_random_bytes_secure
+#undef gcry_randomize
+#undef gcry_create_nonce
+
+#undef gcry_sexp_alist
+#undef gcry_sexp_append
+#undef gcry_sexp_build
+#undef gcry_sexp_build_array
+#undef gcry_sexp_cadr
+#undef gcry_sexp_canon_len
+#undef gcry_sexp_car
+#undef gcry_sexp_cdr
+#undef gcry_sexp_cons
+#undef gcry_sexp_create
+#undef gcry_sexp_dump
+#undef gcry_sexp_find_token
+#undef gcry_sexp_length
+#undef gcry_sexp_new
+#undef gcry_sexp_nth
+#undef gcry_sexp_nth_data
+#undef gcry_sexp_nth_mpi
+#undef gcry_sexp_prepend
+#undef gcry_sexp_release
+#undef gcry_sexp_sprint
+#undef gcry_sexp_sscan
+#undef gcry_sexp_vlist
+#undef gcry_sexp_nth_string
+
+#undef gcry_mpi_add
+#undef gcry_mpi_add_ui
+#undef gcry_mpi_addm
+#undef gcry_mpi_aprint
+#undef gcry_mpi_clear_bit
+#undef gcry_mpi_clear_flag
+#undef gcry_mpi_clear_highbit
+#undef gcry_mpi_cmp
+#undef gcry_mpi_cmp_ui
+#undef gcry_mpi_copy
+#undef gcry_mpi_div
+#undef gcry_mpi_dump
+#undef gcry_mpi_gcd
+#undef gcry_mpi_get_flag
+#undef gcry_mpi_get_nbits
+#undef gcry_mpi_get_opaque
+#undef gcry_mpi_invm
+#undef gcry_mpi_mod
+#undef gcry_mpi_mul
+#undef gcry_mpi_mul_2exp
+#undef gcry_mpi_mul_ui
+#undef gcry_mpi_mulm
+#undef gcry_mpi_new
+#undef gcry_mpi_powm
+#undef gcry_mpi_print
+#undef gcry_mpi_randomize
+#undef gcry_mpi_release
+#undef gcry_mpi_rshift
+#undef gcry_mpi_lshift
+#undef gcry_mpi_scan
+#undef gcry_mpi_set
+#undef gcry_mpi_set_bit
+#undef gcry_mpi_set_flag
+#undef gcry_mpi_set_highbit
+#undef gcry_mpi_set_opaque
+#undef gcry_mpi_set_ui
+#undef gcry_mpi_snew
+#undef gcry_mpi_sub
+#undef gcry_mpi_sub_ui
+#undef gcry_mpi_subm
+#undef gcry_mpi_swap
+#undef gcry_mpi_test_bit
+
+
+/* Now mark all symbols. */
+
+MARK_VISIBLE (gcry_check_version)
+MARK_VISIBLE (gcry_control)
+
+MARK_VISIBLE (gcry_set_allocation_handler)
+MARK_VISIBLE (gcry_set_fatalerror_handler)
+MARK_VISIBLE (gcry_set_gettext_handler)
+MARK_VISIBLE (gcry_set_log_handler)
+MARK_VISIBLE (gcry_set_outofcore_handler)
+MARK_VISIBLE (gcry_set_progress_handler)
+MARK_VISIBLE (gcry_err_code_from_errno)
+MARK_VISIBLE (gcry_err_code_to_errno)
+MARK_VISIBLE (gcry_err_make_from_errno)
+MARK_VISIBLE (gcry_error_from_errno)
+MARK_VISIBLE (gcry_strerror)
+MARK_VISIBLE (gcry_strsource)
+
+MARK_VISIBLE (gcry_free)
+MARK_VISIBLE (gcry_malloc)
+MARK_VISIBLE (gcry_malloc_secure)
+MARK_VISIBLE (gcry_calloc)
+MARK_VISIBLE (gcry_calloc_secure)
+MARK_VISIBLE (gcry_realloc)
+MARK_VISIBLE (gcry_strdup)
+MARK_VISIBLE (gcry_is_secure)
+MARK_VISIBLE (gcry_xcalloc)
+MARK_VISIBLE (gcry_xcalloc_secure)
+MARK_VISIBLE (gcry_xmalloc)
+MARK_VISIBLE (gcry_xmalloc_secure)
+MARK_VISIBLE (gcry_xrealloc)
+MARK_VISIBLE (gcry_xstrdup)
+
+MARK_VISIBLE (gcry_md_algo_info)
+MARK_VISIBLE (gcry_md_algo_name)
+MARK_VISIBLE (gcry_md_close)
+MARK_VISIBLE (gcry_md_copy)
+MARK_VISIBLE (gcry_md_ctl)
+MARK_VISIBLE (gcry_md_enable)
+MARK_VISIBLE (gcry_md_get)
+MARK_VISIBLE (gcry_md_get_algo)
+MARK_VISIBLE (gcry_md_get_algo_dlen)
+MARK_VISIBLE (gcry_md_hash_buffer)
+MARK_VISIBLE (gcry_md_info)
+MARK_VISIBLE (gcry_md_is_enabled)
+MARK_VISIBLE (gcry_md_is_secure)
+MARK_VISIBLE (gcry_md_map_name)
+MARK_VISIBLE (gcry_md_open)
+MARK_VISIBLE (gcry_md_read)
+MARK_VISIBLE (gcry_md_reset)
+MARK_VISIBLE (gcry_md_setkey)
+MARK_VISIBLE (gcry_md_write)
+MARK_VISIBLE (gcry_md_debug)
+
+MARK_VISIBLE (gcry_cipher_algo_info)
+MARK_VISIBLE (gcry_cipher_algo_name)
+MARK_VISIBLE (gcry_cipher_close)
+MARK_VISIBLE (gcry_cipher_setkey)
+MARK_VISIBLE (gcry_cipher_setiv)
+MARK_VISIBLE (gcry_cipher_setctr)
+MARK_VISIBLE (gcry_cipher_ctl)
+MARK_VISIBLE (gcry_cipher_decrypt)
+MARK_VISIBLE (gcry_cipher_encrypt)
+MARK_VISIBLE (gcry_cipher_get_algo_blklen)
+MARK_VISIBLE (gcry_cipher_get_algo_keylen)
+MARK_VISIBLE (gcry_cipher_info)
+MARK_VISIBLE (gcry_cipher_map_name)
+MARK_VISIBLE (gcry_cipher_mode_from_oid)
+MARK_VISIBLE (gcry_cipher_open)
+
+MARK_VISIBLE (gcry_pk_algo_info)
+MARK_VISIBLE (gcry_pk_algo_name)
+MARK_VISIBLE (gcry_pk_ctl)
+MARK_VISIBLE (gcry_pk_decrypt)
+MARK_VISIBLE (gcry_pk_encrypt)
+MARK_VISIBLE (gcry_pk_genkey)
+MARK_VISIBLE (gcry_pk_get_keygrip)
+MARK_VISIBLE (gcry_pk_get_curve)
+MARK_VISIBLE (gcry_pk_get_param)
+MARK_VISIBLE (gcry_pk_get_nbits)
+MARK_VISIBLE (gcry_pk_map_name)
+MARK_VISIBLE (gcry_pk_sign)
+MARK_VISIBLE (gcry_pk_testkey)
+MARK_VISIBLE (gcry_pk_verify)
+
+MARK_VISIBLE (gcry_kdf_derive)
+
+MARK_VISIBLE (gcry_prime_check)
+MARK_VISIBLE (gcry_prime_generate)
+MARK_VISIBLE (gcry_prime_group_generator)
+MARK_VISIBLE (gcry_prime_release_factors)
+
+MARK_VISIBLE (gcry_random_add_bytes)
+MARK_VISIBLE (gcry_random_bytes)
+MARK_VISIBLE (gcry_random_bytes_secure)
+MARK_VISIBLE (gcry_randomize)
+MARK_VISIBLE (gcry_create_nonce)
+
+MARK_VISIBLE (gcry_sexp_alist)
+MARK_VISIBLE (gcry_sexp_append)
+MARK_VISIBLE (gcry_sexp_build)
+MARK_VISIBLE (gcry_sexp_build_array)
+MARK_VISIBLE (gcry_sexp_cadr)
+MARK_VISIBLE (gcry_sexp_canon_len)
+MARK_VISIBLE (gcry_sexp_car)
+MARK_VISIBLE (gcry_sexp_cdr)
+MARK_VISIBLE (gcry_sexp_cons)
+MARK_VISIBLE (gcry_sexp_create)
+MARK_VISIBLE (gcry_sexp_dump)
+MARK_VISIBLE (gcry_sexp_find_token)
+MARK_VISIBLE (gcry_sexp_length)
+MARK_VISIBLE (gcry_sexp_new)
+MARK_VISIBLE (gcry_sexp_nth)
+MARK_VISIBLE (gcry_sexp_nth_data)
+MARK_VISIBLE (gcry_sexp_nth_mpi)
+MARK_VISIBLE (gcry_sexp_prepend)
+MARK_VISIBLE (gcry_sexp_release)
+MARK_VISIBLE (gcry_sexp_sprint)
+MARK_VISIBLE (gcry_sexp_sscan)
+MARK_VISIBLE (gcry_sexp_vlist)
+MARK_VISIBLE (gcry_sexp_nth_string)
+
+MARK_VISIBLE (gcry_mpi_add)
+MARK_VISIBLE (gcry_mpi_add_ui)
+MARK_VISIBLE (gcry_mpi_addm)
+MARK_VISIBLE (gcry_mpi_aprint)
+MARK_VISIBLE (gcry_mpi_clear_bit)
+MARK_VISIBLE (gcry_mpi_clear_flag)
+MARK_VISIBLE (gcry_mpi_clear_highbit)
+MARK_VISIBLE (gcry_mpi_cmp)
+MARK_VISIBLE (gcry_mpi_cmp_ui)
+MARK_VISIBLE (gcry_mpi_copy)
+MARK_VISIBLE (gcry_mpi_div)
+MARK_VISIBLE (gcry_mpi_dump)
+MARK_VISIBLE (gcry_mpi_gcd)
+MARK_VISIBLE (gcry_mpi_get_flag)
+MARK_VISIBLE (gcry_mpi_get_nbits)
+MARK_VISIBLE (gcry_mpi_get_opaque)
+MARK_VISIBLE (gcry_mpi_invm)
+MARK_VISIBLE (gcry_mpi_mod)
+MARK_VISIBLE (gcry_mpi_mul)
+MARK_VISIBLE (gcry_mpi_mul_2exp)
+MARK_VISIBLE (gcry_mpi_mul_ui)
+MARK_VISIBLE (gcry_mpi_mulm)
+MARK_VISIBLE (gcry_mpi_new)
+MARK_VISIBLE (gcry_mpi_powm)
+MARK_VISIBLE (gcry_mpi_print)
+MARK_VISIBLE (gcry_mpi_randomize)
+MARK_VISIBLE (gcry_mpi_release)
+MARK_VISIBLE (gcry_mpi_rshift)
+MARK_VISIBLE (gcry_mpi_lshift)
+MARK_VISIBLE (gcry_mpi_scan)
+MARK_VISIBLE (gcry_mpi_set)
+MARK_VISIBLE (gcry_mpi_set_bit)
+MARK_VISIBLE (gcry_mpi_set_flag)
+MARK_VISIBLE (gcry_mpi_set_highbit)
+MARK_VISIBLE (gcry_mpi_set_opaque)
+MARK_VISIBLE (gcry_mpi_set_ui)
+MARK_VISIBLE (gcry_mpi_snew)
+MARK_VISIBLE (gcry_mpi_sub)
+MARK_VISIBLE (gcry_mpi_sub_ui)
+MARK_VISIBLE (gcry_mpi_subm)
+MARK_VISIBLE (gcry_mpi_swap)
+MARK_VISIBLE (gcry_mpi_test_bit)
+
+
+
+#undef MARK_VISIBLE
+#endif /*_GCRY_INCLUDED_BY_VISIBILITY_C*/
+
+#endif /*GCRY_VISIBILITY_H*/
diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h
index 70c0fb4..f537d50 100644
--- a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h
+++ b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h
@@ -25,56 +25,19 @@
#include <grub/dl.h>
#include <grub/crypto.h>
-#undef WORDS_BIGENDIAN
-
-#ifdef GRUB_CPU_WORDS_BIGENDIAN
-#define WORDS_BIGENDIAN 1
-#endif
+#include <sys/types.h>
#undef __GNU_LIBRARY__
#define __GNU_LIBRARY__ 1
-#define DIM ARRAY_SIZE
-
-typedef grub_uint64_t u64;
-typedef grub_uint32_t u32;
-typedef grub_uint16_t u16;
-typedef grub_uint8_t byte;
-typedef grub_size_t size_t;
-
#define U64_C(c) (c ## ULL)
-#define _gcry_burn_stack grub_burn_stack
-#define log_error(fmt, args...) grub_dprintf ("crypto", fmt, ## args)
-
-
#define PUBKEY_FLAG_NO_BLINDING (1 << 0)
#define CIPHER_INFO_NO_WEAK_KEY 1
#define HAVE_U64_TYPEDEF 1
-typedef union {
- int a;
- short b;
- char c[1];
- long d;
-#ifdef HAVE_U64_TYPEDEF
- u64 e;
-#endif
- float f;
- double g;
-} PROPERLY_ALIGNED_TYPE;
-
-#define gcry_assert(x) grub_assert_real(GRUB_FILE, __LINE__, x)
-
-static inline void
-grub_assert_real (const char *file, int line, int cond)
-{
- if (!cond)
- grub_fatal ("Assertion failed at %s:%d\n", file, line);
-}
-
/* Selftests are in separate modules. */
static inline char *
selftest (void)
@@ -90,11 +53,6 @@ fips_mode (void)
#ifdef GRUB_UTIL
#pragma GCC diagnostic ignored "-Wshadow"
-static inline void *
-memcpy (void *dest, const void *src, grub_size_t n)
-{
- return grub_memcpy (dest, src, n);
-}
static inline void *
memset (void *s, int c, grub_size_t n)
@@ -102,13 +60,17 @@ memset (void *s, int c, grub_size_t n)
return grub_memset (s, c, n);
}
-static inline int
-memcmp (const void *s1, const void *s2, grub_size_t n)
-{
- return grub_memcmp (s1, s2, n);
-}
#pragma GCC diagnostic error "-Wshadow"
#endif
+#define DBG_CIPHER 0
+
+#include <string.h>
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#include <grub/gcrypt/g10lib.h>
+#include <grub/gcrypt/gcrypt.h>
+
+#define gcry_mpi_mod _gcry_mpi_mod
+
#endif
diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c
new file mode 100644
index 0000000..94f9d65
--- /dev/null
+++ b/grub-core/lib/libgcrypt_wrap/mem.c
@@ -0,0 +1,133 @@
+#include <grub/gcrypt/gcrypt.h>
+#include <grub/gcrypt/gpg-error.h>
+#include <grub/term.h>
+#include <grub/crypto.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+void *
+gcry_malloc (size_t n)
+{
+ return grub_malloc (n);
+}
+
+void *
+gcry_malloc_secure (size_t n)
+{
+ return grub_malloc (n);
+}
+
+void
+gcry_free (void *a)
+{
+ grub_free (a);
+}
+
+int
+gcry_is_secure (const void *a __attribute__ ((unused)))
+{
+ return 0;
+}
+
+/* FIXME: implement "exit". */
+void *
+gcry_xcalloc (size_t n, size_t m)
+{
+ void *ret;
+ ret = grub_zalloc (n * m);
+ if (!ret)
+ grub_fatal ("gcry_xcalloc failed");
+ return ret;
+}
+
+void *
+gcry_xmalloc_secure (size_t n)
+{
+ void *ret;
+ ret = grub_malloc (n);
+ if (!ret)
+ grub_fatal ("gcry_xmalloc failed");
+ return ret;
+}
+
+void *
+gcry_xcalloc_secure (size_t n, size_t m)
+{
+ void *ret;
+ ret = grub_zalloc (n * m);
+ if (!ret)
+ grub_fatal ("gcry_xcalloc failed");
+ return ret;
+}
+
+void *
+gcry_xmalloc (size_t n)
+{
+ void *ret;
+ ret = grub_malloc (n);
+ if (!ret)
+ grub_fatal ("gcry_xmalloc failed");
+ return ret;
+}
+
+void *
+gcry_xrealloc (void *a, size_t n)
+{
+ void *ret;
+ ret = grub_realloc (a, n);
+ if (!ret)
+ grub_fatal ("gcry_xrealloc failed");
+ return ret;
+}
+
+void
+_gcry_check_heap (const void *a __attribute__ ((unused)))
+{
+
+}
+
+void _gcry_log_printf (const char *fmt, ...)
+{
+ va_list args;
+ const char *debug = grub_env_get ("debug");
+
+ if (! debug)
+ return;
+
+ if (grub_strword (debug, "all") || grub_strword (debug, "gcrypt"))
+ {
+ grub_printf ("gcrypt: ");
+ va_start (args, fmt);
+ grub_vprintf (fmt, args);
+ va_end (args);
+ grub_refresh ();
+ }
+}
+
+void _gcry_log_bug (const char *fmt, ...)
+{
+ va_list args;
+
+ grub_printf ("gcrypt bug: ");
+ va_start (args, fmt);
+ grub_vprintf (fmt, args);
+ va_end (args);
+ grub_refresh ();
+ grub_abort ();
+}
+
+gcry_err_code_t
+gpg_error_from_syserror (void)
+{
+ switch (grub_errno)
+ {
+ case GRUB_ERR_NONE:
+ return GPG_ERR_NO_ERROR;
+ case GRUB_ERR_OUT_OF_MEMORY:
+ return GPG_ERR_OUT_OF_MEMORY;
+ default:
+ return GPG_ERR_GENERAL;
+ }
+}
diff --git a/grub-core/lib/posix_wrap/stdio.h b/grub-core/lib/posix_wrap/stdio.h
index e6b1178..d5a8b75 100644
--- a/grub-core/lib/posix_wrap/stdio.h
+++ b/grub-core/lib/posix_wrap/stdio.h
@@ -21,13 +21,14 @@
#include <grub/misc.h>
#include <grub/file.h>
+#include <sys/types.h>
typedef struct grub_file FILE;
#define EOF -1
static inline int
-snprintf (char *str, size_t n, const char *fmt, ...)
+snprintf (char *str, grub_size_t n, const char *fmt, ...)
{
va_list ap;
int ret;
diff --git a/grub-core/lib/posix_wrap/string.h b/grub-core/lib/posix_wrap/string.h
index 77fbe38..53ef0a9 100644
--- a/grub-core/lib/posix_wrap/string.h
+++ b/grub-core/lib/posix_wrap/string.h
@@ -20,6 +20,9 @@
#define GRUB_POSIX_STRING_H 1
#include <grub/misc.h>
+#include <sys/types.h>
+
+#define HAVE_STRCASECMP 1
static inline grub_size_t
strlen (const char *s)
@@ -47,13 +50,19 @@ memcpy (void *dest, const void *src, grub_size_t n)
}
static inline int
-memcmp (const void *s1, const void *s2, size_t n)
+memcmp (const void *s1, const void *s2, grub_size_t n)
{
return grub_memcmp (s1, s2, n);
}
#endif
+static inline void
+bcopy (const void *src, void *dest, grub_size_t n)
+{
+ grub_memcpy (dest, src, n);
+}
+
static inline char *
strcpy (char *dest, const char *src)
{
@@ -73,7 +82,7 @@ strchr (const char *s, int c)
}
static inline char *
-strncpy (char *dest, const char *src, size_t n)
+strncpy (char *dest, const char *src, grub_size_t n)
{
return grub_strncpy (dest, src, n);
}
@@ -85,7 +94,7 @@ strcat (char *dest, const char *src)
}
static inline char *
-strncat (char *dest, const char *src, size_t n)
+strncat (char *dest, const char *src, grub_size_t n)
{
return grub_strncat (dest, src, n);
}
@@ -97,7 +106,7 @@ strcoll (const char *s1, const char *s2)
}
static inline void *
-memchr (const void *s, int c, size_t n)
+memchr (const void *s, int c, grub_size_t n)
{
return grub_memchr (s, c, n);
}
diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h
index 0e61b72..62a2672 100644
--- a/grub-core/lib/posix_wrap/sys/types.h
+++ b/grub-core/lib/posix_wrap/sys/types.h
@@ -42,6 +42,21 @@ typedef grub_int16_t int16_t;
typedef grub_int32_t int32_t;
typedef grub_int64_t int64_t;
+#define HAVE_U64_TYPEDEF 1
+typedef grub_uint64_t u64;
+#define HAVE_U32_TYPEDEF 1
+typedef grub_uint32_t u32;
+#define HAVE_U16_TYPEDEF 1
+typedef grub_uint16_t u16;
+#define HAVE_BYTE_TYPEDEF 1
+typedef grub_uint8_t byte;
+
+#define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG
+#define SIZEOF_UNSIGNED_INT 4
+#define SIZEOF_UNSIGNED_LONG_LONG 8
+#define SIZEOF_UNSIGNED_SHORT 2
+#define SIZEOF_UINT64_T 8
+
#ifdef GRUB_CPU_WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#else
diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c
index a45040a..350066d 100644
--- a/grub-core/lib/relocator.c
+++ b/grub-core/lib/relocator.c
@@ -1313,6 +1313,45 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
return GRUB_ERR_NONE;
}
+/* Context for grub_relocator_alloc_chunk_align. */
+struct grub_relocator_alloc_chunk_align_ctx
+{
+ grub_phys_addr_t min_addr, max_addr;
+ grub_size_t size, align;
+ int preference;
+ struct grub_relocator_chunk *chunk;
+ int found;
+};
+
+/* Helper for grub_relocator_alloc_chunk_align. */
+static int
+grub_relocator_alloc_chunk_align_iter (grub_uint64_t addr, grub_uint64_t sz,
+ grub_memory_type_t type, void *data)
+{
+ struct grub_relocator_alloc_chunk_align_ctx *ctx = data;
+ grub_uint64_t candidate;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ candidate = ALIGN_UP (addr, ctx->align);
+ if (candidate < ctx->min_addr)
+ candidate = ALIGN_UP (ctx->min_addr, ctx->align);
+ if (candidate + ctx->size > addr + sz
+ || candidate > ALIGN_DOWN (ctx->max_addr, ctx->align))
+ return 0;
+ if (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
+ candidate = ALIGN_DOWN (min (addr + sz - ctx->size, ctx->max_addr),
+ ctx->align);
+ if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH
+ && candidate > ctx->chunk->target))
+ ctx->chunk->target = candidate;
+ if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_LOW
+ && candidate < ctx->chunk->target))
+ ctx->chunk->target = candidate;
+ ctx->found = 1;
+ return 0;
+}
+
grub_err_t
grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
grub_relocator_chunk_t *out,
@@ -1322,8 +1361,15 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
int preference,
int avoid_efi_boot_services)
{
+ struct grub_relocator_alloc_chunk_align_ctx ctx = {
+ .min_addr = min_addr,
+ .max_addr = max_addr,
+ .size = size,
+ .align = align,
+ .preference = preference,
+ .found = 0
+ };
grub_addr_t min_addr2 = 0, max_addr2;
- struct grub_relocator_chunk *chunk;
if (max_addr > ~size)
max_addr = ~size;
@@ -1335,24 +1381,24 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
grub_dprintf ("relocator", "chunks = %p\n", rel->chunks);
- chunk = grub_malloc (sizeof (struct grub_relocator_chunk));
- if (!chunk)
+ ctx.chunk = grub_malloc (sizeof (struct grub_relocator_chunk));
+ if (!ctx.chunk)
return grub_errno;
if (malloc_in_range (rel, min_addr, max_addr, align,
- size, chunk,
+ size, ctx.chunk,
preference != GRUB_RELOCATOR_PREFERENCE_HIGH, 1))
{
grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n",
- (unsigned long long) chunk->src,
- (unsigned long long) chunk->src);
+ (unsigned long long) ctx.chunk->src,
+ (unsigned long long) ctx.chunk->src);
grub_dprintf ("relocator", "chunks = %p\n", rel->chunks);
- chunk->target = chunk->src;
- chunk->size = size;
- chunk->next = rel->chunks;
- rel->chunks = chunk;
- chunk->srcv = grub_map_memory (chunk->src, chunk->size);
- *out = chunk;
+ ctx.chunk->target = ctx.chunk->src;
+ ctx.chunk->size = size;
+ ctx.chunk->next = rel->chunks;
+ rel->chunks = ctx.chunk;
+ ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size);
+ *out = ctx.chunk;
return GRUB_ERR_NONE;
}
@@ -1364,14 +1410,14 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
do
{
if (malloc_in_range (rel, min_addr2, max_addr2, align,
- size, chunk, 1, 1))
+ size, ctx.chunk, 1, 1))
break;
if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1,
- size, chunk, 0, 1))
+ size, ctx.chunk, 0, 1))
{
- if (rel->postchunks > chunk->src)
- rel->postchunks = chunk->src;
+ if (rel->postchunks > ctx.chunk->src)
+ rel->postchunks = ctx.chunk->src;
break;
}
@@ -1380,58 +1426,33 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
while (0);
{
- int found = 0;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t sz,
- grub_memory_type_t type)
- {
- grub_uint64_t candidate;
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
- candidate = ALIGN_UP (addr, align);
- if (candidate < min_addr)
- candidate = ALIGN_UP (min_addr, align);
- if (candidate + size > addr + sz
- || candidate > ALIGN_DOWN (max_addr, align))
- return 0;
- if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
- candidate = ALIGN_DOWN (min (addr + sz - size, max_addr), align);
- if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_HIGH
- && candidate > chunk->target))
- chunk->target = candidate;
- if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_LOW
- && candidate < chunk->target))
- chunk->target = candidate;
- found = 1;
- return 0;
- }
-
#ifdef GRUB_MACHINE_EFI
- grub_efi_mmap_iterate (hook, avoid_efi_boot_services);
+ grub_efi_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx,
+ avoid_efi_boot_services);
#elif defined (__powerpc__)
(void) avoid_efi_boot_services;
- grub_machine_mmap_iterate (hook);
+ grub_machine_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx);
#else
(void) avoid_efi_boot_services;
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx);
#endif
- if (!found)
+ if (!ctx.found)
return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target");
}
while (1)
{
struct grub_relocator_chunk *chunk2;
for (chunk2 = rel->chunks; chunk2; chunk2 = chunk2->next)
- if ((chunk2->target <= chunk->target
- && chunk->target < chunk2->target + chunk2->size)
- || (chunk->target <= chunk2->target && chunk2->target
- < chunk->target + size))
+ if ((chunk2->target <= ctx.chunk->target
+ && ctx.chunk->target < chunk2->target + chunk2->size)
+ || (ctx.chunk->target <= chunk2->target && chunk2->target
+ < ctx.chunk->target + size))
{
if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
- chunk->target = ALIGN_DOWN (chunk2->target, align);
+ ctx.chunk->target = ALIGN_DOWN (chunk2->target, align);
else
- chunk->target = ALIGN_UP (chunk2->target + chunk2->size, align);
+ ctx.chunk->target = ALIGN_UP (chunk2->target + chunk2->size,
+ align);
break;
}
if (!chunk2)
@@ -1441,23 +1462,23 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
grub_dprintf ("relocator", "relocators_size=%ld\n",
(unsigned long) rel->relocators_size);
- if (chunk->src < chunk->target)
+ if (ctx.chunk->src < ctx.chunk->target)
rel->relocators_size += grub_relocator_backward_size;
- if (chunk->src > chunk->target)
+ if (ctx.chunk->src > ctx.chunk->target)
rel->relocators_size += grub_relocator_forward_size;
grub_dprintf ("relocator", "relocators_size=%ld\n",
(unsigned long) rel->relocators_size);
- chunk->size = size;
- chunk->next = rel->chunks;
- rel->chunks = chunk;
+ ctx.chunk->size = size;
+ ctx.chunk->next = rel->chunks;
+ rel->chunks = ctx.chunk;
grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
rel->chunks->next);
- chunk->srcv = grub_map_memory (chunk->src, chunk->size);
- *out = chunk;
+ ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size);
+ *out = ctx.chunk;
#ifdef DEBUG_RELOCATOR
- grub_memset (chunk->srcv, 0xfa, chunk->size);
+ grub_memset (ctx.chunk->srcv, 0xfa, ctx.chunk->size);
grub_mm_check ();
#endif
return GRUB_ERR_NONE;
diff --git a/grub-core/lib/xzembed/xz_dec_lzma2.c b/grub-core/lib/xzembed/xz_dec_lzma2.c
index 7899e9e..4f4fb85 100644
--- a/grub-core/lib/xzembed/xz_dec_lzma2.c
+++ b/grub-core/lib/xzembed/xz_dec_lzma2.c
@@ -327,9 +327,9 @@ static inline uint32_t dict_get(
/*
* Put one byte into the dictionary. It is assumed that there is space for it.
*/
-static inline void dict_put(struct dictionary *dict, uint8_t byte)
+static inline void dict_put(struct dictionary *dict, uint8_t b)
{
- dict->buf[dict->pos++] = byte;
+ dict->buf[dict->pos++] = b;
if (dict->full < dict->pos)
dict->full = dict->pos;
diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c
index 6170b0c..f5a86eb 100644
--- a/grub-core/lib/xzembed/xz_dec_stream.c
+++ b/grub-core/lib/xzembed/xz_dec_stream.c
@@ -197,20 +197,20 @@ static bool fill_temp(struct xz_dec *s, struct xz_buf *b)
static enum xz_ret dec_vli(struct xz_dec *s,
const uint8_t *in, size_t *in_pos, size_t in_size)
{
- uint8_t byte;
+ uint8_t b;
if (s->pos == 0)
s->vli = 0;
while (*in_pos < in_size) {
- byte = in[*in_pos];
+ b = in[*in_pos];
++*in_pos;
- s->vli |= (vli_type)(byte & 0x7F) << s->pos;
+ s->vli |= (vli_type)(b & 0x7F) << s->pos;
- if ((byte & 0x80) == 0) {
+ if ((b & 0x80) == 0) {
/* Don't allow non-minimal encodings. */
- if (byte == 0 && s->pos != 0)
+ if (b == 0 && s->pos != 0)
return XZ_DATA_ERROR;
s->pos = 0;
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 3f3e6e3..c0fed80 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -35,6 +35,10 @@
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/net.h>
+#if defined (__i386__) || defined (__x86_64__)
+#include <grub/macho.h>
+#include <grub/i386/macho.h>
+#endif
GRUB_MOD_LICENSE ("GPLv3+");
@@ -198,6 +202,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_device_path_t *dp = 0;
grub_efi_loaded_image_t *loaded_image;
char *filename;
+ void *boot_image = 0;
grub_efi_handle_t dev_handle = 0;
if (argc == 0)
@@ -278,7 +283,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size)
+ boot_image = (void *) ((grub_addr_t) address);
+ if (grub_file_read (file, boot_image, size) != size)
{
if (grub_errno == GRUB_ERR_NONE)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -287,9 +293,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
+#if defined (__i386__) || defined (__x86_64__)
+ if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
+ {
+ struct grub_macho_fat_header *head = boot_image;
+ if (head->magic
+ == grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC))
+ {
+ grub_uint32_t i;
+ struct grub_macho_fat_arch *archs
+ = (struct grub_macho_fat_arch *) (head + 1);
+ for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++)
+ {
+ if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype))
+ break;
+ }
+ if (i == grub_cpu_to_le32 (head->nfat_arch))
+ {
+ grub_error (GRUB_ERR_BAD_OS, "no compatible arch found");
+ goto fail;
+ }
+ if (grub_cpu_to_le32 (archs[i].offset)
+ > ~grub_cpu_to_le32 (archs[i].size)
+ || grub_cpu_to_le32 (archs[i].offset)
+ + grub_cpu_to_le32 (archs[i].size)
+ > (grub_size_t) size)
+ {
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+ filename);
+ goto fail;
+ }
+ boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset);
+ size = grub_cpu_to_le32 (archs[i].size);
+ }
+ }
+#endif
+
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
- (void *) ((grub_addr_t) address), size,
- &image_handle);
+ boot_image, size,
+ &image_handle);
if (status != GRUB_EFI_SUCCESS)
{
if (status == GRUB_EFI_OUT_OF_RESOURCES)
diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
index 6e024e4..9b86158 100644
--- a/grub-core/loader/i386/bsd.c
+++ b/grub-core/loader/i386/bsd.c
@@ -269,81 +269,93 @@ struct grub_e820_mmap
#define GRUB_E820_NVS 4
#define GRUB_E820_BADRAM 5
-static void
-generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf)
+/* Context for generate_e820_mmap. */
+struct generate_e820_mmap_ctx
{
- int count = 0;
- struct grub_e820_mmap *mmap = buf;
+ int count;
+ struct grub_e820_mmap *mmap;
struct grub_e820_mmap prev, cur;
+};
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- cur.addr = addr;
- cur.size = size;
- switch (type)
- {
- case GRUB_MEMORY_AVAILABLE:
- cur.type = GRUB_E820_RAM;
- break;
-
- case GRUB_MEMORY_ACPI:
- cur.type = GRUB_E820_ACPI;
- break;
+/* Helper for generate_e820_mmap. */
+static int
+generate_e820_mmap_iter (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type, void *data)
+{
+ struct generate_e820_mmap_ctx *ctx = data;
- case GRUB_MEMORY_NVS:
- cur.type = GRUB_E820_NVS;
- break;
+ ctx->cur.addr = addr;
+ ctx->cur.size = size;
+ switch (type)
+ {
+ case GRUB_MEMORY_AVAILABLE:
+ ctx->cur.type = GRUB_E820_RAM;
+ break;
+
+ case GRUB_MEMORY_ACPI:
+ ctx->cur.type = GRUB_E820_ACPI;
+ break;
+
+ case GRUB_MEMORY_NVS:
+ ctx->cur.type = GRUB_E820_NVS;
+ break;
+
+ default:
+ case GRUB_MEMORY_CODE:
+ case GRUB_MEMORY_RESERVED:
+ ctx->cur.type = GRUB_E820_RESERVED;
+ break;
+ }
- default:
- case GRUB_MEMORY_CODE:
- case GRUB_MEMORY_RESERVED:
- cur.type = GRUB_E820_RESERVED;
- break;
- }
+ /* Merge regions if possible. */
+ if (ctx->count && ctx->cur.type == ctx->prev.type
+ && ctx->cur.addr == ctx->prev.addr + ctx->prev.size)
+ {
+ ctx->prev.size += ctx->cur.size;
+ if (ctx->mmap)
+ ctx->mmap[-1] = ctx->prev;
+ }
+ else
+ {
+ if (ctx->mmap)
+ *ctx->mmap++ = ctx->cur;
+ ctx->prev = ctx->cur;
+ ctx->count++;
+ }
- /* Merge regions if possible. */
- if (count && cur.type == prev.type && cur.addr == prev.addr + prev.size)
- {
- prev.size += cur.size;
- if (mmap)
- mmap[-1] = prev;
- }
- else
+ if (kernel_type == KERNEL_TYPE_OPENBSD && ctx->prev.addr < 0x100000
+ && ctx->prev.addr + ctx->prev.size > 0x100000)
+ {
+ ctx->cur.addr = 0x100000;
+ ctx->cur.size = ctx->prev.addr + ctx->prev.size - 0x100000;
+ ctx->cur.type = ctx->prev.type;
+ ctx->prev.size = 0x100000 - ctx->prev.addr;
+ if (ctx->mmap)
{
- if (mmap)
- *mmap++ = cur;
- prev = cur;
- count++;
+ ctx->mmap[-1] = ctx->prev;
+ ctx->mmap[0] = ctx->cur;
+ ctx->mmap++;
}
+ ctx->prev = ctx->cur;
+ ctx->count++;
+ }
- if (kernel_type == KERNEL_TYPE_OPENBSD && prev.addr < 0x100000
- && prev.addr + prev.size > 0x100000)
- {
- cur.addr = 0x100000;
- cur.size = prev.addr + prev.size - 0x100000;
- cur.type = prev.type;
- prev.size = 0x100000 - prev.addr;
- if (mmap)
- {
- mmap[-1] = prev;
- mmap[0] = cur;
- mmap++;
- }
- prev = cur;
- count++;
- }
+ return 0;
+}
- return 0;
- }
+static void
+generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf)
+{
+ struct generate_e820_mmap_ctx ctx = {
+ .count = 0,
+ .mmap = buf
+ };
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (generate_e820_mmap_iter, &ctx);
if (len)
- *len = count * sizeof (struct grub_e820_mmap);
- *cnt = count;
+ *len = ctx.count * sizeof (struct grub_e820_mmap);
+ *cnt = ctx.count;
return;
}
@@ -1299,7 +1311,7 @@ grub_bsd_load_aout (grub_file_t file, const char *filename)
bss_size);
}
-static int NESTED_FUNC_ATTR
+static int
grub_bsd_elf32_size_hook (grub_elf_t elf __attribute__ ((unused)),
Elf32_Phdr *phdr, void *arg __attribute__ ((unused)))
{
@@ -1341,7 +1353,7 @@ grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load)
return GRUB_ERR_NONE;
}
-static int NESTED_FUNC_ATTR
+static int
grub_bsd_elf64_size_hook (grub_elf_t elf __attribute__ ((unused)),
Elf64_Phdr *phdr, void *arg __attribute__ ((unused)))
{
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index fc0ebe7..92cabfb 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -150,23 +150,25 @@ find_efi_mmap_size (void)
#endif
+/* Helper for find_mmap_size. */
+static int
+count_hook (grub_uint64_t addr __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
+ grub_memory_type_t type __attribute__ ((unused)), void *data)
+{
+ grub_size_t *count = data;
+
+ (*count)++;
+ return 0;
+}
+
/* Find the optimal number of pages for the memory map. */
static grub_size_t
find_mmap_size (void)
{
grub_size_t count = 0, mmap_size;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
- grub_uint64_t size __attribute__ ((unused)),
- grub_memory_type_t type __attribute__ ((unused)))
- {
- count++;
- return 0;
- }
-
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (count_hook, &count);
mmap_size = count * sizeof (struct grub_e820_mmap);
@@ -372,17 +374,96 @@ grub_linux_setup_video (struct linux_kernel_params *params)
return GRUB_ERR_NONE;
}
+/* Context for grub_linux_boot. */
+struct grub_linux_boot_ctx
+{
+ grub_addr_t real_mode_target;
+ grub_size_t real_size;
+ struct linux_kernel_params *params;
+ int e820_num;
+};
+
+/* Helper for grub_linux_boot. */
+static int
+grub_linux_boot_mmap_find (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type, void *data)
+{
+ struct grub_linux_boot_ctx *ctx = data;
+
+ /* We must put real mode code in the traditional space. */
+ if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000)
+ return 0;
+
+ if (addr + size < 0x10000)
+ return 0;
+
+ if (addr < 0x10000)
+ {
+ size += addr - 0x10000;
+ addr = 0x10000;
+ }
+
+ if (addr + size > 0x90000)
+ size = 0x90000 - addr;
+
+ if (ctx->real_size + efi_mmap_size > size)
+ return 0;
+
+ grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n",
+ (unsigned long) addr,
+ (unsigned) size,
+ (unsigned) (ctx->real_size + efi_mmap_size));
+ ctx->real_mode_target = ((addr + size) - (ctx->real_size + efi_mmap_size));
+ return 1;
+}
+
+static int
+grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type, void *data)
+{
+ struct grub_linux_boot_ctx *ctx = data;
+
+ grub_uint32_t e820_type;
+ switch (type)
+ {
+ case GRUB_MEMORY_AVAILABLE:
+ e820_type = GRUB_E820_RAM;
+ break;
+
+ case GRUB_MEMORY_ACPI:
+ e820_type = GRUB_E820_ACPI;
+ break;
+
+ case GRUB_MEMORY_NVS:
+ e820_type = GRUB_E820_NVS;
+ break;
+
+ case GRUB_MEMORY_BADRAM:
+ e820_type = GRUB_E820_BADRAM;
+ break;
+
+ default:
+ e820_type = GRUB_E820_RESERVED;
+ }
+ if (grub_e820_add_region (ctx->params->e820_map, &ctx->e820_num,
+ addr, size, e820_type))
+ return 1;
+
+ return 0;
+}
+
static grub_err_t
grub_linux_boot (void)
{
- int e820_num;
grub_err_t err = 0;
const char *modevar;
char *tmp;
struct grub_relocator32_state state;
void *real_mode_mem;
- grub_addr_t real_mode_target = 0;
- grub_size_t real_size, mmap_size;
+ struct grub_linux_boot_ctx ctx = {
+ .real_mode_target = 0
+ };
+ grub_size_t mmap_size;
grub_size_t cl_offset;
#ifdef GRUB_MACHINE_IEEE1275
@@ -484,7 +565,7 @@ grub_linux_boot (void)
if (cl_offset < ((grub_size_t) linux_params.setup_sects << GRUB_DISK_SECTOR_BITS))
cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects
<< GRUB_DISK_SECTOR_BITS), 4096);
- real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096);
+ ctx.real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096);
#ifdef GRUB_MACHINE_EFI
efi_mmap_size = find_efi_mmap_size ();
@@ -493,118 +574,51 @@ grub_linux_boot (void)
#endif
grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n",
- (unsigned) real_size, (unsigned) mmap_size);
-
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- /* We must put real mode code in the traditional space. */
- if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000)
- return 0;
-
- if (addr + size < 0x10000)
- return 0;
-
- if (addr < 0x10000)
- {
- size += addr - 0x10000;
- addr = 0x10000;
- }
+ (unsigned) ctx.real_size, (unsigned) mmap_size);
- if (addr + size > 0x90000)
- size = 0x90000 - addr;
-
- if (real_size + efi_mmap_size > size)
- return 0;
-
- grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n",
- (unsigned long) addr,
- (unsigned) size,
- (unsigned) (real_size + efi_mmap_size));
- real_mode_target = ((addr + size) - (real_size + efi_mmap_size));
- return 1;
- }
#ifdef GRUB_MACHINE_EFI
- grub_efi_mmap_iterate (hook, 1);
- if (! real_mode_target)
- grub_efi_mmap_iterate (hook, 0);
+ grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 1);
+ if (! ctx.real_mode_target)
+ grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 0);
#else
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (grub_linux_boot_mmap_find, &ctx);
#endif
grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n",
- (unsigned long) real_mode_target,
- (unsigned) real_size,
+ (unsigned long) ctx.real_mode_target,
+ (unsigned) ctx.real_size,
(unsigned) efi_mmap_size);
- if (! real_mode_target)
+ if (! ctx.real_mode_target)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
- real_mode_target,
- (real_size + efi_mmap_size));
+ ctx.real_mode_target,
+ (ctx.real_size + efi_mmap_size));
if (err)
return err;
real_mode_mem = get_virtual_current_address (ch);
}
- efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size;
+ efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size;
grub_dprintf ("linux", "real_mode_mem = %lx\n",
(unsigned long) real_mode_mem);
- struct linux_kernel_params *params;
-
- params = real_mode_mem;
+ ctx.params = real_mode_mem;
- *params = linux_params;
- params->cmd_line_ptr = real_mode_target + cl_offset;
- grub_memcpy ((char *) params + cl_offset, linux_cmdline,
+ *ctx.params = linux_params;
+ ctx.params->cmd_line_ptr = ctx.real_mode_target + cl_offset;
+ grub_memcpy ((char *) ctx.params + cl_offset, linux_cmdline,
maximal_cmdline_size);
grub_dprintf ("linux", "code32_start = %x\n",
- (unsigned) params->code32_start);
-
- auto int NESTED_FUNC_ATTR hook_fill (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook_fill (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- grub_uint32_t e820_type;
- switch (type)
- {
- case GRUB_MEMORY_AVAILABLE:
- e820_type = GRUB_E820_RAM;
- break;
-
- case GRUB_MEMORY_ACPI:
- e820_type = GRUB_E820_ACPI;
- break;
-
- case GRUB_MEMORY_NVS:
- e820_type = GRUB_E820_NVS;
- break;
-
- case GRUB_MEMORY_BADRAM:
- e820_type = GRUB_E820_BADRAM;
- break;
-
- default:
- e820_type = GRUB_E820_RESERVED;
- }
- if (grub_e820_add_region (params->e820_map, &e820_num,
- addr, size, e820_type))
- return 1;
-
- return 0;
- }
+ (unsigned) ctx.params->code32_start);
- e820_num = 0;
- if (grub_mmap_iterate (hook_fill))
+ ctx.e820_num = 0;
+ if (grub_mmap_iterate (grub_linux_boot_mmap_fill, &ctx))
return grub_errno;
- params->mmap_size = e820_num;
+ ctx.params->mmap_size = ctx.e820_num;
#ifdef GRUB_MACHINE_EFI
{
@@ -617,33 +631,33 @@ grub_linux_boot (void)
return err;
/* Note that no boot services are available from here. */
- efi_mmap_target = real_mode_target
+ efi_mmap_target = ctx.real_mode_target
+ ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem);
/* Pass EFI parameters. */
- if (grub_le_to_cpu16 (params->version) >= 0x0208)
+ if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208)
{
- params->v0208.efi_mem_desc_size = efi_desc_size;
- params->v0208.efi_mem_desc_version = efi_desc_version;
- params->v0208.efi_mmap = efi_mmap_target;
- params->v0208.efi_mmap_size = efi_mmap_size;
+ ctx.params->v0208.efi_mem_desc_size = efi_desc_size;
+ ctx.params->v0208.efi_mem_desc_version = efi_desc_version;
+ ctx.params->v0208.efi_mmap = efi_mmap_target;
+ ctx.params->v0208.efi_mmap_size = efi_mmap_size;
#ifdef __x86_64__
- params->v0208.efi_mmap_hi = (efi_mmap_target >> 32);
+ ctx.params->v0208.efi_mmap_hi = (efi_mmap_target >> 32);
#endif
}
- else if (grub_le_to_cpu16 (params->version) >= 0x0206)
+ else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0206)
{
- params->v0206.efi_mem_desc_size = efi_desc_size;
- params->v0206.efi_mem_desc_version = efi_desc_version;
- params->v0206.efi_mmap = efi_mmap_target;
- params->v0206.efi_mmap_size = efi_mmap_size;
+ ctx.params->v0206.efi_mem_desc_size = efi_desc_size;
+ ctx.params->v0206.efi_mem_desc_version = efi_desc_version;
+ ctx.params->v0206.efi_mmap = efi_mmap_target;
+ ctx.params->v0206.efi_mmap_size = efi_mmap_size;
}
- else if (grub_le_to_cpu16 (params->version) >= 0x0204)
+ else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0204)
{
- params->v0204.efi_mem_desc_size = efi_desc_size;
- params->v0204.efi_mem_desc_version = efi_desc_version;
- params->v0204.efi_mmap = efi_mmap_target;
- params->v0204.efi_mmap_size = efi_mmap_size;
+ ctx.params->v0204.efi_mem_desc_size = efi_desc_size;
+ ctx.params->v0204.efi_mem_desc_version = efi_desc_version;
+ ctx.params->v0204.efi_mmap = efi_mmap_target;
+ ctx.params->v0204.efi_mmap_size = efi_mmap_size;
}
}
#endif
@@ -651,9 +665,9 @@ grub_linux_boot (void)
/* FIXME. */
/* asm volatile ("lidt %0" : : "m" (idt_desc)); */
state.ebp = state.edi = state.ebx = 0;
- state.esi = real_mode_target;
- state.esp = real_mode_target;
- state.eip = params->code32_start;
+ state.esi = ctx.real_mode_target;
+ state.esp = ctx.real_mode_target;
+ state.eip = ctx.params->code32_start;
return grub_relocator32_boot (relocator, state, 0);
}
@@ -1101,8 +1115,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
worse than that of Linux 2.3.xx, so avoid the last 64kb. */
addr_max -= 0x10000;
- addr_min = (grub_addr_t) prot_mode_target + prot_init_space
- + page_align (size);
+ addr_min = (grub_addr_t) prot_mode_target + prot_init_space;
/* Put the initrd as high as possible, 4KiB aligned. */
addr = (addr_max - size) & ~0xFFF;
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
index 8fc40d7..18fd367 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -224,48 +224,50 @@ grub_multiboot_get_mbi_size (void)
return ret;
}
+/* Helper for grub_fill_multiboot_mmap. */
+static int
+grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type, void *data)
+{
+ struct multiboot_mmap_entry **mmap_entry = data;
+
+ (*mmap_entry)->addr = addr;
+ (*mmap_entry)->len = size;
+ switch (type)
+ {
+ case GRUB_MEMORY_AVAILABLE:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_AVAILABLE;
+ break;
+
+ case GRUB_MEMORY_ACPI:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
+ break;
+
+ case GRUB_MEMORY_NVS:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_NVS;
+ break;
+
+ case GRUB_MEMORY_BADRAM:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_BADRAM;
+ break;
+
+ default:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_RESERVED;
+ break;
+ }
+ (*mmap_entry)->size = sizeof (struct multiboot_mmap_entry) - sizeof ((*mmap_entry)->size);
+ (*mmap_entry)++;
+
+ return 0;
+}
+
/* Fill previously allocated Multiboot mmap. */
static void
grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
{
struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- mmap_entry->addr = addr;
- mmap_entry->len = size;
- switch (type)
- {
- case GRUB_MEMORY_AVAILABLE:
- mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE;
- break;
-
- case GRUB_MEMORY_ACPI:
- mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
- break;
-
- case GRUB_MEMORY_NVS:
- mmap_entry->type = MULTIBOOT_MEMORY_NVS;
- break;
-
- case GRUB_MEMORY_BADRAM:
- mmap_entry->type = MULTIBOOT_MEMORY_BADRAM;
- break;
-
- default:
- mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
- break;
- }
- mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size);
- mmap_entry++;
-
- return 0;
- }
-
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (grub_fill_multiboot_mmap_iter, &mmap_entry);
}
#if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT
diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c
index f1eed57..e685c6e 100644
--- a/grub-core/loader/i386/pc/freedos.c
+++ b/grub-core/loader/i386/pc/freedos.c
@@ -32,6 +32,7 @@
#include <grub/video.h>
#include <grub/mm.h>
#include <grub/cpu/relocator.h>
+#include <grub/machine/chainloader.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -40,8 +41,23 @@ static struct grub_relocator *rel;
static grub_uint32_t ebx = 0xffffffff;
#define GRUB_FREEDOS_SEGMENT 0x60
+#define GRUB_FREEDOS_ADDR (GRUB_FREEDOS_SEGMENT << 4)
#define GRUB_FREEDOS_STACK_SEGMENT 0x1fe0
-#define GRUB_FREEDOS_STACK_POINTER 0x8000
+#define GRUB_FREEDOS_STACK_BPB_POINTER 0x7c00
+#define GRUB_FREEDOS_BPB_ADDR ((GRUB_FREEDOS_STACK_SEGMENT << 4) \
+ + GRUB_FREEDOS_STACK_BPB_POINTER)
+
+/* FreeDOS boot.asm passes register sp as exactly this. Importantly,
+ it must point below the BPB (to avoid overwriting any of it). */
+#define GRUB_FREEDOS_STACK_POINTER (GRUB_FREEDOS_STACK_BPB_POINTER \
+ - 0x60)
+
+/* In this, the additional 8192 bytes are the stack reservation; the
+ remaining parts trivially give the maximum allowed size. */
+#define GRUB_FREEDOS_MAX_SIZE ((GRUB_FREEDOS_STACK_SEGMENT << 4) \
+ + GRUB_FREEDOS_STACK_POINTER \
+ - GRUB_FREEDOS_ADDR \
+ - 8192)
static grub_err_t
grub_freedos_boot (void)
@@ -49,14 +65,16 @@ grub_freedos_boot (void)
struct grub_relocator16_state state = {
.cs = GRUB_FREEDOS_SEGMENT,
.ip = 0,
- .ds = 0,
+
+ .ds = GRUB_FREEDOS_STACK_SEGMENT,
.es = 0,
.fs = 0,
.gs = 0,
.ss = GRUB_FREEDOS_STACK_SEGMENT,
.sp = GRUB_FREEDOS_STACK_POINTER,
+ .ebp = GRUB_FREEDOS_STACK_BPB_POINTER,
.ebx = ebx,
- .edx = 0,
+ .edx = ebx,
.a20 = 1
};
grub_video_set_mode ("text", 0, 0);
@@ -79,8 +97,9 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)),
{
grub_file_t file = 0;
grub_err_t err;
- void *kernelsys;
+ void *bs, *kernelsys;
grub_size_t kernelsyssize;
+ grub_device_t dev;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -95,12 +114,44 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)),
if (! file)
goto fail;
+ {
+ grub_relocator_chunk_t ch;
+ err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_BPB_ADDR,
+ GRUB_DISK_SECTOR_SIZE);
+ if (err)
+ goto fail;
+ bs = get_virtual_current_address (ch);
+ }
+
ebx = grub_get_root_biosnumber ();
+ dev = grub_device_open (0);
+
+ if (dev && dev->disk)
+ {
+ err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs);
+ if (err)
+ {
+ grub_device_close (dev);
+ goto fail;
+ }
+ grub_chainloader_patch_bpb (bs, dev, ebx);
+ }
+
+ if (dev)
+ grub_device_close (dev);
kernelsyssize = grub_file_size (file);
+
+ if (kernelsyssize > GRUB_FREEDOS_MAX_SIZE)
+ {
+ grub_error (GRUB_ERR_BAD_OS,
+ N_("file `%s' is too large"), argv[0]);
+ goto fail;
+ }
+
{
grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_SEGMENT << 4,
+ err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_ADDR,
kernelsyssize);
if (err)
goto fail;
diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c
index b41dfd2..7dc12a8 100644
--- a/grub-core/loader/i386/pc/plan9.c
+++ b/grub-core/loader/i386/pc/plan9.c
@@ -102,248 +102,281 @@ grub_plan9_unload (void)
return GRUB_ERR_NONE;
}
-static grub_err_t
-grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
+/* Context for grub_cmd_plan9. */
+struct grub_cmd_plan9_ctx
{
- grub_file_t file = 0;
- void *mem;
- grub_size_t memsize, padsize;
- struct grub_plan9_header hdr;
- char *config, *configptr;
- grub_size_t configsize;
- char *pmap = NULL;
- grub_size_t pmapalloc = 256;
- grub_size_t pmapptr = 0;
- int noslash = 1;
- char prefixes[5][10] = {"dos", "plan9", "ntfs", "linux", "linuxswap"};
+ grub_extcmd_context_t ctxt;
+ grub_file_t file;
+ char *pmap;
+ grub_size_t pmapalloc;
+ grub_size_t pmapptr;
+ int noslash;
int prefixescnt[5];
- char *bootdisk = NULL, *bootpart = NULL, *bootpath = NULL;
+ char *bootdisk, *bootpart;
+};
- auto int fill_partition (grub_disk_t disk,
- const grub_partition_t partition);
- int fill_partition (grub_disk_t disk,
- const grub_partition_t partition)
- {
- int file_disk = 0;
- int pstart, pend;
- if (!noslash)
- {
- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap))
- return 1;
- pmap[pmapptr++] = '/';
- }
- noslash = 0;
+static const char prefixes[5][10] = {
+ "dos", "plan9", "ntfs", "linux", "linuxswap"
+};
- file_disk = file->device->disk && disk->id == file->device->disk->id
- && disk->dev->id == file->device->disk->dev->id;
+/* Helper for grub_cmd_plan9. */
+static int
+fill_partition (grub_disk_t disk, const grub_partition_t partition, void *data)
+{
+ struct grub_cmd_plan9_ctx *fill_ctx = data;
+ int file_disk = 0;
+ int pstart, pend;
- pstart = pmapptr;
- if (grub_strcmp (partition->partmap->name, "plan") == 0)
- {
- unsigned ptr = partition->index + sizeof ("part ") - 1;
- grub_err_t err;
- disk->partition = partition->parent;
- do
- {
- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap))
- return 1;
- err = grub_disk_read (disk, 1, ptr, 1, pmap + pmapptr);
- if (err)
- {
- disk->partition = 0;
- return err;
- }
- ptr++;
- pmapptr++;
- }
- while (grub_isalpha (pmap[pmapptr - 1])
- || grub_isdigit (pmap[pmapptr - 1]));
- pmapptr--;
- }
- else
- {
- char name[50];
- int c = 0;
- if (grub_strcmp (partition->partmap->name, "msdos") == 0)
- {
- switch (partition->msdostype)
- {
- case GRUB_PC_PARTITION_TYPE_PLAN9:
- c = 1;
- break;
- case GRUB_PC_PARTITION_TYPE_NTFS:
- c = 2;
- break;
- case GRUB_PC_PARTITION_TYPE_MINIX:
- case GRUB_PC_PARTITION_TYPE_LINUX_MINIX:
- case GRUB_PC_PARTITION_TYPE_EXT2FS:
- c = 3;
- break;
- case GRUB_PC_PARTITION_TYPE_LINUX_SWAP:
- c = 4;
- break;
- }
- }
+ if (!fill_ctx->noslash)
+ {
+ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
+ (void **) &fill_ctx->pmap))
+ return 1;
+ fill_ctx->pmap[fill_ctx->pmapptr++] = '/';
+ }
+ fill_ctx->noslash = 0;
- if (prefixescnt[c] == 0)
- grub_strcpy (name, prefixes[c]);
- else
- grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c],
- prefixescnt[c]);
- prefixescnt[c]++;
- if (grub_extend_alloc (pmapptr + grub_strlen (name) + 1,
- &pmapalloc, (void **) &pmap))
- return 1;
- grub_strcpy (pmap + pmapptr, name);
- pmapptr += grub_strlen (name);
- }
- pend = pmapptr;
- if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc,
- (void **) &pmap))
- return 1;
- pmap[pmapptr++] = ' ';
- grub_snprintf (pmap + pmapptr, 25 + 5 + 25,
- "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T,
- grub_partition_get_start (partition),
- grub_partition_get_start (partition)
- + grub_partition_get_len (partition));
- if (file_disk && grub_partition_get_start (partition)
- == grub_partition_get_start (file->device->disk->partition)
- && grub_partition_get_len (partition)
- == grub_partition_get_len (file->device->disk->partition))
- {
- grub_free (bootpart);
- bootpart = grub_strndup (pmap + pstart, pend - pstart);
- }
+ file_disk = fill_ctx->file->device->disk
+ && disk->id == fill_ctx->file->device->disk->id
+ && disk->dev->id == fill_ctx->file->device->disk->dev->id;
- pmapptr += grub_strlen (pmap + pmapptr);
- return 0;
- }
+ pstart = fill_ctx->pmapptr;
+ if (grub_strcmp (partition->partmap->name, "plan") == 0)
+ {
+ unsigned ptr = partition->index + sizeof ("part ") - 1;
+ grub_err_t err;
+ disk->partition = partition->parent;
+ do
+ {
+ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
+ (void **) &fill_ctx->pmap))
+ return 1;
+ err = grub_disk_read (disk, 1, ptr, 1,
+ fill_ctx->pmap + fill_ctx->pmapptr);
+ if (err)
+ {
+ disk->partition = 0;
+ return err;
+ }
+ ptr++;
+ fill_ctx->pmapptr++;
+ }
+ while (grub_isalpha (fill_ctx->pmap[fill_ctx->pmapptr - 1])
+ || grub_isdigit (fill_ctx->pmap[fill_ctx->pmapptr - 1]));
+ fill_ctx->pmapptr--;
+ }
+ else
+ {
+ char name[50];
+ int c = 0;
+ if (grub_strcmp (partition->partmap->name, "msdos") == 0)
+ {
+ switch (partition->msdostype)
+ {
+ case GRUB_PC_PARTITION_TYPE_PLAN9:
+ c = 1;
+ break;
+ case GRUB_PC_PARTITION_TYPE_NTFS:
+ c = 2;
+ break;
+ case GRUB_PC_PARTITION_TYPE_MINIX:
+ case GRUB_PC_PARTITION_TYPE_LINUX_MINIX:
+ case GRUB_PC_PARTITION_TYPE_EXT2FS:
+ c = 3;
+ break;
+ case GRUB_PC_PARTITION_TYPE_LINUX_SWAP:
+ c = 4;
+ break;
+ }
+ }
- auto int fill_disk (const char *name);
- int fill_disk (const char *name)
- {
- grub_device_t dev;
- char *plan9name = NULL;
- unsigned i;
- int file_disk = 0;
+ if (fill_ctx->prefixescnt[c] == 0)
+ grub_strcpy (name, prefixes[c]);
+ else
+ grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c],
+ fill_ctx->prefixescnt[c]);
+ fill_ctx->prefixescnt[c]++;
+ if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (name) + 1,
+ &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap))
+ return 1;
+ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, name);
+ fill_ctx->pmapptr += grub_strlen (name);
+ }
+ pend = fill_ctx->pmapptr;
+ if (grub_extend_alloc (fill_ctx->pmapptr + 2 + 25 + 5 + 25,
+ &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap))
+ return 1;
+ fill_ctx->pmap[fill_ctx->pmapptr++] = ' ';
+ grub_snprintf (fill_ctx->pmap + fill_ctx->pmapptr, 25 + 5 + 25,
+ "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T,
+ grub_partition_get_start (partition),
+ grub_partition_get_start (partition)
+ + grub_partition_get_len (partition));
+ if (file_disk && grub_partition_get_start (partition)
+ == grub_partition_get_start (fill_ctx->file->device->disk->partition)
+ && grub_partition_get_len (partition)
+ == grub_partition_get_len (fill_ctx->file->device->disk->partition))
+ {
+ grub_free (fill_ctx->bootpart);
+ fill_ctx->bootpart = grub_strndup (fill_ctx->pmap + pstart,
+ pend - pstart);
+ }
- dev = grub_device_open (name);
- if (!dev)
- {
- grub_print_error ();
- return 0;
- }
- if (!dev->disk)
+ fill_ctx->pmapptr += grub_strlen (fill_ctx->pmap + fill_ctx->pmapptr);
+ return 0;
+}
+
+/* Helper for grub_cmd_plan9. */
+static int
+fill_disk (const char *name, void *data)
+{
+ struct grub_cmd_plan9_ctx *fill_ctx = data;
+ grub_device_t dev;
+ char *plan9name = NULL;
+ unsigned i;
+ int file_disk = 0;
+
+ dev = grub_device_open (name);
+ if (!dev)
+ {
+ grub_print_error ();
+ return 0;
+ }
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
+ return 0;
+ }
+ file_disk = fill_ctx->file->device->disk
+ && dev->disk->id == fill_ctx->file->device->disk->id
+ && dev->disk->dev->id == fill_ctx->file->device->disk->dev->id;
+ for (i = 0;
+ fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i]; i++)
+ if (grub_strncmp (name, fill_ctx->ctxt->state[0].args[i],
+ grub_strlen (name)) == 0
+ && fill_ctx->ctxt->state[0].args[i][grub_strlen (name)] == '=')
+ break;
+ if (fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i])
+ plan9name = grub_strdup (fill_ctx->ctxt->state[0].args[i]
+ + grub_strlen (name) + 1);
+ else
+ switch (dev->disk->dev->id)
{
- grub_device_close (dev);
- return 0;
- }
- file_disk = file->device->disk && dev->disk->id == file->device->disk->id
- && dev->disk->dev->id == file->device->disk->dev->id;
- for (i = 0; ctxt->state[0].args && ctxt->state[0].args[i]; i++)
- if (grub_strncmp (name, ctxt->state[0].args[i], grub_strlen (name)) == 0
- && ctxt->state[0].args[i][grub_strlen (name)] == '=')
+ case GRUB_DISK_DEVICE_BIOSDISK_ID:
+ if (dev->disk->id & 0x80)
+ plan9name = grub_xasprintf ("sdB%u",
+ (unsigned) (dev->disk->id & 0x7f));
+ else
+ plan9name = grub_xasprintf ("fd%u",
+ (unsigned) (dev->disk->id & 0x7f));
break;
- if (ctxt->state[0].args && ctxt->state[0].args[i])
- plan9name = grub_strdup (ctxt->state[0].args[i] + grub_strlen (name) + 1);
- else
- switch (dev->disk->dev->id)
+ /* Shouldn't happen as Plan9 doesn't work on these platforms. */
+ case GRUB_DISK_DEVICE_OFDISK_ID:
+ case GRUB_DISK_DEVICE_EFIDISK_ID:
+
+ /* Plan9 doesn't see those. */
+ default:
+
+ /* Not sure how to handle those. */
+ case GRUB_DISK_DEVICE_NAND_ID:
+ if (!file_disk)
+ {
+ grub_device_close (dev);
+ return 0;
+ }
+
+ /* if it's the disk the kernel is loaded from we need to name
+ it nevertheless. */
+ plan9name = grub_strdup ("sdZ0");
+ break;
+
+ case GRUB_DISK_DEVICE_ATA_ID:
{
- case GRUB_DISK_DEVICE_BIOSDISK_ID:
- if (dev->disk->id & 0x80)
- plan9name = grub_xasprintf ("sdB%u",
- (unsigned) (dev->disk->id & 0x7f));
+ int unit;
+ if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1)
+ unit = 0;
else
- plan9name = grub_xasprintf ("fd%u",
- (unsigned) (dev->disk->id & 0x7f));
- break;
- /* Shouldn't happen as Plan9 doesn't work on these platforms. */
- case GRUB_DISK_DEVICE_OFDISK_ID:
- case GRUB_DISK_DEVICE_EFIDISK_ID:
-
- /* Plan9 doesn't see those. */
- default:
-
- /* Not sure how to handle those. */
- case GRUB_DISK_DEVICE_NAND_ID:
- if (!file_disk)
- {
- grub_device_close (dev);
- return 0;
- }
-
- /* if it's the disk the kernel is loaded from we need to name
- it nevertheless. */
- plan9name = grub_strdup ("sdZ0");
- break;
-
- case GRUB_DISK_DEVICE_ATA_ID:
+ unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0);
+ plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2);
+ }
+ break;
+ case GRUB_DISK_DEVICE_SCSI_ID:
+ if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff)
+ == GRUB_SCSI_SUBSYSTEM_PATA)
{
int unit;
if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1)
unit = 0;
else
- unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0);
+ unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1,
+ 0, 0);
plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2);
+ break;
}
- break;
- case GRUB_DISK_DEVICE_SCSI_ID:
- if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff)
- == GRUB_SCSI_SUBSYSTEM_PATA)
- {
- int unit;
- if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1)
- unit = 0;
- else
- unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1,
- 0, 0);
- plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2);
- break;
- }
-
- /* FIXME: how does Plan9 number controllers?
- We probably need save the SCSI devices and sort them */
- plan9name
- = grub_xasprintf ("sd0%u", (unsigned)
- ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT)
- & 0xf));
- break;
- }
- if (!plan9name)
- {
- grub_print_error ();
- return 0;
- }
- if (grub_extend_alloc (pmapptr + grub_strlen (plan9name)
- + sizeof ("part="), &pmapalloc,
- (void **) &pmap))
- {
- grub_free (plan9name);
- return 1;
+
+ /* FIXME: how does Plan9 number controllers?
+ We probably need save the SCSI devices and sort them */
+ plan9name
+ = grub_xasprintf ("sd0%u", (unsigned)
+ ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT)
+ & 0xf));
+ break;
}
- grub_strcpy (pmap + pmapptr, plan9name);
- pmapptr += grub_strlen (plan9name);
- if (!file_disk)
+ if (!plan9name)
+ {
+ grub_print_error ();
+ return 0;
+ }
+ if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (plan9name)
+ + sizeof ("part="), &fill_ctx->pmapalloc,
+ (void **) &fill_ctx->pmap))
+ {
grub_free (plan9name);
- else
- {
- grub_free (bootdisk);
- bootdisk = plan9name;
- }
- grub_strcpy (pmap + pmapptr, "part=");
- pmapptr += sizeof ("part=") - 1;
-
- noslash = 1;
- grub_memset (prefixescnt, 0, sizeof (prefixescnt));
- if (grub_partition_iterate (dev->disk, fill_partition))
- return 1;
- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap))
return 1;
- pmap[pmapptr++] = '\n';
+ }
+ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, plan9name);
+ fill_ctx->pmapptr += grub_strlen (plan9name);
+ if (!file_disk)
+ grub_free (plan9name);
+ else
+ {
+ grub_free (fill_ctx->bootdisk);
+ fill_ctx->bootdisk = plan9name;
+ }
+ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, "part=");
+ fill_ctx->pmapptr += sizeof ("part=") - 1;
+
+ fill_ctx->noslash = 1;
+ grub_memset (fill_ctx->prefixescnt, 0, sizeof (fill_ctx->prefixescnt));
+ if (grub_partition_iterate (dev->disk, fill_partition, fill_ctx))
+ return 1;
+ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc,
+ (void **) &fill_ctx->pmap))
+ return 1;
+ fill_ctx->pmap[fill_ctx->pmapptr++] = '\n';
+
+ return 0;
+}
- return 0;
- }
+static grub_err_t
+grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
+{
+ struct grub_cmd_plan9_ctx fill_ctx = {
+ .ctxt = ctxt,
+ .file = 0,
+ .pmap = NULL,
+ .pmapalloc = 256,
+ .pmapptr = 0,
+ .noslash = 1,
+ .bootdisk = NULL,
+ .bootpart = NULL
+ };
+ void *mem;
+ grub_size_t memsize, padsize;
+ struct grub_plan9_header hdr;
+ char *config, *configptr;
+ grub_size_t configsize;
+ char *bootpath = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -354,21 +387,21 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
if (!rel)
goto fail;
- file = grub_file_open (argv[0]);
- if (! file)
+ fill_ctx.file = grub_file_open (argv[0]);
+ if (! fill_ctx.file)
goto fail;
- pmap = grub_malloc (pmapalloc);
- if (!pmap)
+ fill_ctx.pmap = grub_malloc (fill_ctx.pmapalloc);
+ if (!fill_ctx.pmap)
goto fail;
- if (grub_disk_dev_iterate (fill_disk))
+ if (grub_disk_dev_iterate (fill_disk, &fill_ctx))
goto fail;
- if (grub_extend_alloc (pmapptr + 1, &pmapalloc,
- (void **) &pmap))
+ if (grub_extend_alloc (fill_ctx.pmapptr + 1, &fill_ctx.pmapalloc,
+ (void **) &fill_ctx.pmap))
goto fail;
- pmap[pmapptr] = 0;
+ fill_ctx.pmap[fill_ctx.pmapptr] = 0;
{
char *file_name = grub_strchr (argv[0], ')');
@@ -379,17 +412,19 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
if (*file_name)
file_name++;
- if (bootpart)
- bootpath = grub_xasprintf ("%s!%s!%s", bootdisk, bootpart, file_name);
+ if (fill_ctx.bootpart)
+ bootpath = grub_xasprintf ("%s!%s!%s", fill_ctx.bootdisk,
+ fill_ctx.bootpart, file_name);
else
- bootpath = grub_xasprintf ("%s!%s", bootdisk, file_name);
- grub_free (bootdisk);
- grub_free (bootpart);
+ bootpath = grub_xasprintf ("%s!%s", fill_ctx.bootdisk, file_name);
+ grub_free (fill_ctx.bootdisk);
+ grub_free (fill_ctx.bootpart);
}
if (!bootpath)
goto fail;
- if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr))
+ if (grub_file_read (fill_ctx.file, &hdr,
+ sizeof (hdr)) != (grub_ssize_t) sizeof (hdr))
{
if (!grub_errno)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -420,7 +455,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
configsize += grub_strlen (argv[i]) + 1;
}
configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1;
- configsize += pmapptr;
+ configsize += fill_ctx.pmapptr;
/* Terminating \0. */
configsize++;
@@ -452,7 +487,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
*configptr++ = '\n';
}
}
- configptr = grub_stpcpy (configptr, pmap);
+ configptr = grub_stpcpy (configptr, fill_ctx.pmap);
{
grub_relocator_chunk_t ch;
@@ -471,7 +506,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
grub_memcpy (ptr, &hdr, sizeof (hdr));
ptr += sizeof (hdr);
- if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size))
+ if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.text_size))
!= (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size))
{
if (!grub_errno)
@@ -487,7 +522,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
grub_memset (ptr, 0, padsize);
ptr += padsize;
- if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size))
+ if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.data_size))
!= (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size))
{
if (!grub_errno)
@@ -508,10 +543,10 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
return GRUB_ERR_NONE;
fail:
- grub_free (pmap);
+ grub_free (fill_ctx.pmap);
- if (file)
- grub_file_close (file);
+ if (fill_ctx.file)
+ grub_file_close (fill_ctx.file);
grub_plan9_unload ();
diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
index fcdf5ff..496e54c 100644
--- a/grub-core/loader/multiboot.c
+++ b/grub-core/loader/multiboot.c
@@ -63,6 +63,18 @@ static int console_required;
static grub_dl_t my_mod;
+/* Helper for grub_get_multiboot_mmap_count. */
+static int
+count_hook (grub_uint64_t addr __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
+ grub_memory_type_t type __attribute__ ((unused)), void *data)
+{
+ grub_size_t *count = data;
+
+ (*count)++;
+ return 0;
+}
+
/* Return the length of the Multiboot mmap that will be needed to allocate
our platform's map. */
grub_uint32_t
@@ -70,16 +82,7 @@ grub_get_multiboot_mmap_count (void)
{
grub_size_t count = 0;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
- grub_uint64_t size __attribute__ ((unused)),
- grub_memory_type_t type __attribute__ ((unused)))
- {
- count++;
- return 0;
- }
-
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (count_hook, &count);
return count;
}
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index a48f020..900793a 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -322,45 +322,47 @@ grub_multiboot_get_mbi_size (void)
+ sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1;
}
-/* Fill previously allocated Multiboot mmap. */
-static void
-grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
+/* Helper for grub_fill_multiboot_mmap. */
+static int
+grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type, void *data)
{
- struct multiboot_mmap_entry *mmap_entry = tag->entries;
+ struct multiboot_mmap_entry **mmap_entry = data;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
+ (*mmap_entry)->addr = addr;
+ (*mmap_entry)->len = size;
+ switch (type)
{
- mmap_entry->addr = addr;
- mmap_entry->len = size;
- switch (type)
- {
- case GRUB_MEMORY_AVAILABLE:
- mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE;
- break;
-
- case GRUB_MEMORY_ACPI:
- mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
- break;
+ case GRUB_MEMORY_AVAILABLE:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_AVAILABLE;
+ break;
- case GRUB_MEMORY_NVS:
- mmap_entry->type = MULTIBOOT_MEMORY_NVS;
- break;
+ case GRUB_MEMORY_ACPI:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
+ break;
- case GRUB_MEMORY_BADRAM:
- mmap_entry->type = MULTIBOOT_MEMORY_BADRAM;
- break;
+ case GRUB_MEMORY_NVS:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_NVS;
+ break;
- default:
- mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
- break;
- }
- mmap_entry++;
+ case GRUB_MEMORY_BADRAM:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_BADRAM;
+ break;
- return 0;
+ default:
+ (*mmap_entry)->type = MULTIBOOT_MEMORY_RESERVED;
+ break;
}
+ (*mmap_entry)++;
+
+ return 0;
+}
+
+/* Fill previously allocated Multiboot mmap. */
+static void
+grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
+{
+ struct multiboot_mmap_entry *mmap_entry = tag->entries;
tag->type = MULTIBOOT_TAG_TYPE_MMAP;
tag->size = sizeof (struct multiboot_tag_mmap)
@@ -368,7 +370,7 @@ grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
tag->entry_size = sizeof (struct multiboot_mmap_entry);
tag->entry_version = 0;
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (grub_fill_multiboot_mmap_iter, &mmap_entry);
}
#if defined (GRUB_MACHINE_PCBIOS)
diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c
index 70e288c..c977941 100644
--- a/grub-core/loader/powerpc/ieee1275/linux.c
+++ b/grub-core/loader/powerpc/ieee1275/linux.c
@@ -51,51 +51,68 @@ static char *linux_args;
typedef void (*kernel_entry_t) (void *, unsigned long, int (void *),
unsigned long, unsigned long);
+/* Context for grub_linux_claimmap_iterate. */
+struct grub_linux_claimmap_iterate_ctx
+{
+ grub_addr_t target;
+ grub_size_t size;
+ grub_size_t align;
+ grub_addr_t found_addr;
+};
+
+/* Helper for grub_linux_claimmap_iterate. */
+static int
+alloc_mem (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
+ void *data)
+{
+ struct grub_linux_claimmap_iterate_ctx *ctx = data;
+
+ grub_uint64_t end = addr + len;
+ addr = ALIGN_UP (addr, ctx->align);
+ ctx->target = ALIGN_UP (ctx->target, ctx->align);
+
+ /* Target above the memory chunk. */
+ if (type != GRUB_MEMORY_AVAILABLE || ctx->target > end)
+ return 0;
+
+ /* Target inside the memory chunk. */
+ if (ctx->target >= addr && ctx->target < end &&
+ ctx->size <= end - ctx->target)
+ {
+ if (grub_claimmap (ctx->target, ctx->size) == GRUB_ERR_NONE)
+ {
+ ctx->found_addr = ctx->target;
+ return 1;
+ }
+ grub_print_error ();
+ }
+ /* Target below the memory chunk. */
+ if (ctx->target < addr && addr + ctx->size <= end)
+ {
+ if (grub_claimmap (addr, ctx->size) == GRUB_ERR_NONE)
+ {
+ ctx->found_addr = addr;
+ return 1;
+ }
+ grub_print_error ();
+ }
+ return 0;
+}
+
static grub_addr_t
grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size,
grub_size_t align)
{
- grub_addr_t found_addr = (grub_addr_t) -1;
-
- auto int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len,
- grub_memory_type_t type);
- int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len,
- grub_memory_type_t type)
- {
- grub_uint64_t end = addr + len;
- addr = ALIGN_UP (addr, align);
- target = ALIGN_UP (target, align);
-
- /* Target above the memory chunk. */
- if (type != GRUB_MEMORY_AVAILABLE || target > end)
- return 0;
-
- /* Target inside the memory chunk. */
- if (target >= addr && target < end && size <= end - target)
- {
- if (grub_claimmap (target, size) == GRUB_ERR_NONE)
- {
- found_addr = target;
- return 1;
- }
- grub_print_error ();
- }
- /* Target below the memory chunk. */
- if (target < addr && addr + size <= end)
- {
- if (grub_claimmap (addr, size) == GRUB_ERR_NONE)
- {
- found_addr = addr;
- return 1;
- }
- grub_print_error ();
- }
- return 0;
- }
+ struct grub_linux_claimmap_iterate_ctx ctx = {
+ .target = target,
+ .size = size,
+ .align = align,
+ .found_addr = (grub_addr_t) -1
+ };
- grub_machine_mmap_iterate (alloc_mem);
+ grub_machine_mmap_iterate (alloc_mem, &ctx);
- return found_addr;
+ return ctx.found_addr;
}
static grub_err_t
diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c
index 06d1df6..c85fcfd 100644
--- a/grub-core/loader/sparc64/ieee1275/linux.c
+++ b/grub-core/loader/sparc64/ieee1275/linux.c
@@ -180,65 +180,76 @@ grub_linux_unload (void)
#define FOUR_MB (4 * 1024 * 1024)
-static grub_addr_t
-alloc_phys (grub_addr_t size)
+/* Context for alloc_phys. */
+struct alloc_phys_ctx
{
- grub_addr_t ret = (grub_addr_t) -1;
+ grub_addr_t size;
+ grub_addr_t ret;
+};
- auto int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len,
- grub_memory_type_t type);
- int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len,
- grub_memory_type_t type)
- {
- grub_addr_t end = addr + len;
+/* Helper for alloc_phys. */
+static int
+alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len,
+ grub_memory_type_t type, void *data)
+{
+ struct alloc_phys_ctx *ctx = data;
+ grub_addr_t end = addr + len;
- if (type != 1)
- return 0;
+ if (type != 1)
+ return 0;
- addr = ALIGN_UP (addr, FOUR_MB);
- if (addr + size >= end)
- return 0;
+ addr = ALIGN_UP (addr, FOUR_MB);
+ if (addr + ctx->size >= end)
+ return 0;
- if (addr >= grub_phys_start && addr < grub_phys_end)
- {
- addr = ALIGN_UP (grub_phys_end, FOUR_MB);
- if (addr + size >= end)
- return 0;
- }
- if ((addr + size) >= grub_phys_start
- && (addr + size) < grub_phys_end)
- {
- addr = ALIGN_UP (grub_phys_end, FOUR_MB);
- if (addr + size >= end)
- return 0;
- }
-
- if (loaded)
- {
- grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB);
-
- if (addr >= linux_paddr && addr < linux_end)
- {
- addr = linux_end;
- if (addr + size >= end)
- return 0;
- }
- if ((addr + size) >= linux_paddr
- && (addr + size) < linux_end)
- {
- addr = linux_end;
- if (addr + size >= end)
- return 0;
- }
- }
-
- ret = addr;
- return 1;
- }
-
- grub_machine_mmap_iterate (choose);
-
- return ret;
+ if (addr >= grub_phys_start && addr < grub_phys_end)
+ {
+ addr = ALIGN_UP (grub_phys_end, FOUR_MB);
+ if (addr + ctx->size >= end)
+ return 0;
+ }
+ if ((addr + ctx->size) >= grub_phys_start
+ && (addr + ctx->size) < grub_phys_end)
+ {
+ addr = ALIGN_UP (grub_phys_end, FOUR_MB);
+ if (addr + ctx->size >= end)
+ return 0;
+ }
+
+ if (loaded)
+ {
+ grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB);
+
+ if (addr >= linux_paddr && addr < linux_end)
+ {
+ addr = linux_end;
+ if (addr + ctx->size >= end)
+ return 0;
+ }
+ if ((addr + ctx->size) >= linux_paddr
+ && (addr + ctx->size) < linux_end)
+ {
+ addr = linux_end;
+ if (addr + ctx->size >= end)
+ return 0;
+ }
+ }
+
+ ctx->ret = addr;
+ return 1;
+}
+
+static grub_addr_t
+alloc_phys (grub_addr_t size)
+{
+ struct alloc_phys_ctx ctx = {
+ .size = size,
+ .ret = (grub_addr_t) -1
+ };
+
+ grub_machine_mmap_iterate (alloc_phys_choose, &ctx);
+
+ return ctx.ret;
}
static grub_err_t
@@ -454,21 +465,23 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
return grub_errno;
}
-static void
-determine_phys_base (void)
+/* Helper for determine_phys_base. */
+static int
+get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__ ((unused)),
+ grub_uint32_t type, void *data __attribute__ ((unused)))
{
- auto int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type);
- int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type)
- {
- if (type != 1)
- return 0;
- if (addr < phys_base)
- phys_base = addr;
+ if (type != 1)
return 0;
- }
+ if (addr < phys_base)
+ phys_base = addr;
+ return 0;
+}
+static void
+determine_phys_base (void)
+{
phys_base = ~(grub_uint64_t) 0;
- grub_machine_mmap_iterate (get_physbase);
+ grub_machine_mmap_iterate (get_physbase, NULL);
}
static void
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
index ed3fc72..8c522f5 100644
--- a/grub-core/loader/xnu.c
+++ b/grub-core/loader/xnu.c
@@ -1017,49 +1017,66 @@ grub_xnu_check_os_bundle_required (char *plistname,
return ret;
}
+/* Context for grub_xnu_scan_dir_for_kexts. */
+struct grub_xnu_scan_dir_for_kexts_ctx
+{
+ char *dirname;
+ const char *osbundlerequired;
+ int maxrecursion;
+};
+
+/* Helper for grub_xnu_scan_dir_for_kexts. */
+static int
+grub_xnu_scan_dir_for_kexts_load (const char *filename,
+ const struct grub_dirhook_info *info,
+ void *data)
+{
+ struct grub_xnu_scan_dir_for_kexts_ctx *ctx = data;
+ char *newdirname;
+
+ if (! info->dir)
+ return 0;
+ if (filename[0] == '.')
+ return 0;
+
+ if (grub_strlen (filename) < 5 ||
+ grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0)
+ return 0;
+
+ newdirname
+ = grub_malloc (grub_strlen (ctx->dirname) + grub_strlen (filename) + 2);
+
+ /* It's a .kext. Try to load it. */
+ if (newdirname)
+ {
+ grub_strcpy (newdirname, ctx->dirname);
+ newdirname[grub_strlen (newdirname) + 1] = 0;
+ newdirname[grub_strlen (newdirname)] = '/';
+ grub_strcpy (newdirname + grub_strlen (newdirname), filename);
+ grub_xnu_load_kext_from_dir (newdirname, ctx->osbundlerequired,
+ ctx->maxrecursion);
+ if (grub_errno == GRUB_ERR_BAD_OS)
+ grub_errno = GRUB_ERR_NONE;
+ grub_free (newdirname);
+ }
+ return 0;
+}
+
/* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */
grub_err_t
grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired,
int maxrecursion)
{
+ struct grub_xnu_scan_dir_for_kexts_ctx ctx = {
+ .dirname = dirname,
+ .osbundlerequired = osbundlerequired,
+ .maxrecursion = maxrecursion
+ };
grub_device_t dev;
char *device_name;
grub_fs_t fs;
const char *path;
- auto int load_hook (const char *filename,
- const struct grub_dirhook_info *info);
- int load_hook (const char *filename, const struct grub_dirhook_info *info)
- {
- char *newdirname;
- if (! info->dir)
- return 0;
- if (filename[0] == '.')
- return 0;
-
- if (grub_strlen (filename) < 5 ||
- grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0)
- return 0;
-
- newdirname
- = grub_malloc (grub_strlen (dirname) + grub_strlen (filename) + 2);
-
- /* It's a .kext. Try to load it. */
- if (newdirname)
- {
- grub_strcpy (newdirname, dirname);
- newdirname[grub_strlen (newdirname) + 1] = 0;
- newdirname[grub_strlen (newdirname)] = '/';
- grub_strcpy (newdirname + grub_strlen (newdirname), filename);
- grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
- maxrecursion);
- if (grub_errno == GRUB_ERR_BAD_OS)
- grub_errno = GRUB_ERR_NONE;
- grub_free (newdirname);
- }
- return 0;
- }
-
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));
@@ -1075,7 +1092,7 @@ grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired,
path++;
if (fs)
- (fs->dir) (dev, path, load_hook);
+ (fs->dir) (dev, path, grub_xnu_scan_dir_for_kexts_load, &ctx);
grub_device_close (dev);
}
grub_free (device_name);
@@ -1083,60 +1100,78 @@ grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired,
return GRUB_ERR_NONE;
}
+/* Context for grub_xnu_load_kext_from_dir. */
+struct grub_xnu_load_kext_from_dir_ctx
+{
+ char *dirname;
+ const char *osbundlerequired;
+ int maxrecursion;
+ char *plistname;
+ char *newdirname;
+ int usemacos;
+};
+
+/* Helper for grub_xnu_load_kext_from_dir. */
+static int
+grub_xnu_load_kext_from_dir_load (const char *filename,
+ const struct grub_dirhook_info *info,
+ void *data)
+{
+ struct grub_xnu_load_kext_from_dir_ctx *ctx = data;
+
+ if (grub_strlen (filename) > 15)
+ return 0;
+ grub_strcpy (ctx->newdirname + grub_strlen (ctx->dirname) + 1, filename);
+
+ /* If the kext contains directory "Contents" all real stuff is in
+ this directory. */
+ if (info->dir && grub_strcasecmp (filename, "Contents") == 0)
+ grub_xnu_load_kext_from_dir (ctx->newdirname, ctx->osbundlerequired,
+ ctx->maxrecursion - 1);
+
+ /* Directory "Plugins" contains nested kexts. */
+ if (info->dir && grub_strcasecmp (filename, "Plugins") == 0)
+ grub_xnu_scan_dir_for_kexts (ctx->newdirname, ctx->osbundlerequired,
+ ctx->maxrecursion - 1);
+
+ /* Directory "MacOS" contains executable, otherwise executable is
+ on the top. */
+ if (info->dir && grub_strcasecmp (filename, "MacOS") == 0)
+ ctx->usemacos = 1;
+
+ /* Info.plist is the file which governs our future actions. */
+ if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
+ && ! ctx->plistname)
+ ctx->plistname = grub_strdup (ctx->newdirname);
+ return 0;
+}
+
/* Load extension DIRNAME. (extensions are directories in xnu) */
grub_err_t
grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired,
int maxrecursion)
{
+ struct grub_xnu_load_kext_from_dir_ctx ctx = {
+ .dirname = dirname,
+ .osbundlerequired = osbundlerequired,
+ .maxrecursion = maxrecursion,
+ .plistname = 0,
+ .usemacos = 0
+ };
grub_device_t dev;
- char *plistname = 0;
- char *newdirname;
char *newpath;
char *device_name;
grub_fs_t fs;
const char *path;
char *binsuffix;
- int usemacos = 0;
grub_file_t binfile;
- auto int load_hook (const char *filename,
- const struct grub_dirhook_info *info);
-
- int load_hook (const char *filename, const struct grub_dirhook_info *info)
- {
- if (grub_strlen (filename) > 15)
- return 0;
- grub_strcpy (newdirname + grub_strlen (dirname) + 1, filename);
-
- /* If the kext contains directory "Contents" all real stuff is in
- this directory. */
- if (info->dir && grub_strcasecmp (filename, "Contents") == 0)
- grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
- maxrecursion - 1);
-
- /* Directory "Plugins" contains nested kexts. */
- if (info->dir && grub_strcasecmp (filename, "Plugins") == 0)
- grub_xnu_scan_dir_for_kexts (newdirname, osbundlerequired,
- maxrecursion - 1);
-
- /* Directory "MacOS" contains executable, otherwise executable is
- on the top. */
- if (info->dir && grub_strcasecmp (filename, "MacOS") == 0)
- usemacos = 1;
-
- /* Info.plist is the file which governs our future actions. */
- if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
- && ! plistname)
- plistname = grub_strdup (newdirname);
- return 0;
- }
-
- newdirname = grub_malloc (grub_strlen (dirname) + 20);
- if (! newdirname)
+ ctx.newdirname = grub_malloc (grub_strlen (dirname) + 20);
+ if (! ctx.newdirname)
return grub_errno;
- grub_strcpy (newdirname, dirname);
- newdirname[grub_strlen (dirname)] = '/';
- newdirname[grub_strlen (dirname) + 1] = 0;
+ grub_strcpy (ctx.newdirname, dirname);
+ ctx.newdirname[grub_strlen (dirname)] = '/';
+ ctx.newdirname[grub_strlen (dirname) + 1] = 0;
device_name = grub_file_get_device_name (dirname);
dev = grub_device_open (device_name);
if (dev)
@@ -1148,18 +1183,18 @@ grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired,
else
path++;
- newpath = grub_strchr (newdirname, ')');
+ newpath = grub_strchr (ctx.newdirname, ')');
if (! newpath)
- newpath = newdirname;
+ newpath = ctx.newdirname;
else
newpath++;
/* Look at the directory. */
if (fs)
- (fs->dir) (dev, path, load_hook);
+ (fs->dir) (dev, path, grub_xnu_load_kext_from_dir_load, &ctx);
- if (plistname && grub_xnu_check_os_bundle_required
- (plistname, osbundlerequired, &binsuffix))
+ if (ctx.plistname && grub_xnu_check_os_bundle_required
+ (ctx.plistname, osbundlerequired, &binsuffix))
{
if (binsuffix)
{
@@ -1168,29 +1203,29 @@ grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired,
+ grub_strlen (binsuffix)
+ sizeof ("/MacOS/"));
grub_strcpy (binname, dirname);
- if (usemacos)
+ if (ctx.usemacos)
grub_strcpy (binname + grub_strlen (binname), "/MacOS/");
else
grub_strcpy (binname + grub_strlen (binname), "/");
grub_strcpy (binname + grub_strlen (binname), binsuffix);
- grub_dprintf ("xnu", "%s:%s\n", plistname, binname);
+ grub_dprintf ("xnu", "%s:%s\n", ctx.plistname, binname);
binfile = grub_file_open (binname);
if (! binfile)
grub_errno = GRUB_ERR_NONE;
/* Load the extension. */
- grub_xnu_load_driver (plistname, binfile,
+ grub_xnu_load_driver (ctx.plistname, binfile,
binname);
grub_free (binname);
grub_free (binsuffix);
}
else
{
- grub_dprintf ("xnu", "%s:0\n", plistname);
- grub_xnu_load_driver (plistname, 0, 0);
+ grub_dprintf ("xnu", "%s:0\n", ctx.plistname);
+ grub_xnu_load_driver (ctx.plistname, 0, 0);
}
}
- grub_free (plistname);
+ grub_free (ctx.plistname);
grub_device_close (dev);
}
grub_free (device_name);
diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c
index c71adad..4f17c8b 100644
--- a/grub-core/mmap/efi/mmap.c
+++ b/grub-core/mmap/efi/mmap.c
@@ -29,7 +29,8 @@
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
grub_err_t
-grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services)
+grub_efi_mmap_iterate (grub_memory_hook_t hook, void *hook_data,
+ int avoid_efi_boot_services)
{
grub_efi_uintn_t mmap_size = 0;
grub_efi_memory_descriptor_t *map_buf = 0;
@@ -69,17 +70,17 @@ grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services)
if (!avoid_efi_boot_services)
{
hook (desc->physical_start, desc->num_pages * 4096,
- GRUB_MEMORY_AVAILABLE);
+ GRUB_MEMORY_AVAILABLE, hook_data);
break;
}
case GRUB_EFI_RUNTIME_SERVICES_CODE:
hook (desc->physical_start, desc->num_pages * 4096,
- GRUB_MEMORY_CODE);
+ GRUB_MEMORY_CODE, hook_data);
break;
case GRUB_EFI_UNUSABLE_MEMORY:
hook (desc->physical_start, desc->num_pages * 4096,
- GRUB_MEMORY_BADRAM);
+ GRUB_MEMORY_BADRAM, hook_data);
break;
default:
@@ -90,7 +91,7 @@ grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services)
if (!avoid_efi_boot_services)
{
hook (desc->physical_start, desc->num_pages * 4096,
- GRUB_MEMORY_AVAILABLE);
+ GRUB_MEMORY_AVAILABLE, hook_data);
break;
}
case GRUB_EFI_RESERVED_MEMORY_TYPE:
@@ -99,24 +100,24 @@ grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services)
case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
case GRUB_EFI_PAL_CODE:
hook (desc->physical_start, desc->num_pages * 4096,
- GRUB_MEMORY_RESERVED);
+ GRUB_MEMORY_RESERVED, hook_data);
break;
case GRUB_EFI_LOADER_CODE:
case GRUB_EFI_LOADER_DATA:
case GRUB_EFI_CONVENTIONAL_MEMORY:
hook (desc->physical_start, desc->num_pages * 4096,
- GRUB_MEMORY_AVAILABLE);
+ GRUB_MEMORY_AVAILABLE, hook_data);
break;
case GRUB_EFI_ACPI_RECLAIM_MEMORY:
hook (desc->physical_start, desc->num_pages * 4096,
- GRUB_MEMORY_ACPI);
+ GRUB_MEMORY_ACPI, hook_data);
break;
case GRUB_EFI_ACPI_MEMORY_NVS:
hook (desc->physical_start, desc->num_pages * 4096,
- GRUB_MEMORY_NVS);
+ GRUB_MEMORY_NVS, hook_data);
break;
}
}
@@ -125,9 +126,9 @@ grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services)
}
grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook)
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
- return grub_efi_mmap_iterate (hook, 0);
+ return grub_efi_mmap_iterate (hook, hook_data, 0);
}
static inline grub_efi_memory_type_t
diff --git a/grub-core/mmap/i386/mmap.c b/grub-core/mmap/i386/mmap.c
index 648a7df..ac45f70 100644
--- a/grub-core/mmap/i386/mmap.c
+++ b/grub-core/mmap/i386/mmap.c
@@ -27,34 +27,48 @@
#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+/* Context for grub_mmap_malign_and_register. */
+struct grub_mmap_malign_and_register_ctx
+{
+ grub_uint64_t align, size, highestlow;
+};
+
+/* Helper for grub_mmap_malign_and_register. */
+static int
+find_hook (grub_uint64_t start, grub_uint64_t rangesize,
+ grub_memory_type_t memtype, void *data)
+{
+ struct grub_mmap_malign_and_register_ctx *ctx = data;
+ grub_uint64_t end = start + rangesize;
+
+ if (memtype != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ if (end > 0x100000)
+ end = 0x100000;
+ if (end > start + ctx->size
+ && ctx->highestlow < ((end - ctx->size)
+ - ((end - ctx->size) & (ctx->align - 1))))
+ ctx->highestlow = (end - ctx->size)
+ - ((end - ctx->size) & (ctx->align - 1));
+ return 0;
+}
+
void *
grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size,
int *handle, int type, int flags)
{
- grub_uint64_t highestlow = 0;
-
- auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize,
- grub_memory_type_t memtype)
- {
- grub_uint64_t end = start + rangesize;
- if (memtype != GRUB_MEMORY_AVAILABLE)
- return 0;
- if (end > 0x100000)
- end = 0x100000;
- if (end > start + size
- && highestlow < ((end - size) - ((end - size) & (align - 1))))
- highestlow = (end - size) - ((end - size) & (align - 1));
- return 0;
- }
+ struct grub_mmap_malign_and_register_ctx ctx = {
+ .align = align,
+ .size = size,
+ .highestlow = 0
+ };
void *ret;
if (flags & GRUB_MMAP_MALLOC_LOW)
{
/* FIXME: use low-memory mm allocation once it's available. */
- grub_mmap_iterate (find_hook);
- ret = (void *) (grub_addr_t) highestlow;
+ grub_mmap_iterate (find_hook, &ctx);
+ ret = (void *) (grub_addr_t) ctx.highestlow;
}
else
ret = grub_memalign (align, size);
diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c
index 12ae4a4..983e220 100644
--- a/grub-core/mmap/i386/pc/mmap.c
+++ b/grub-core/mmap/i386/pc/mmap.c
@@ -50,22 +50,23 @@ struct grub_e820_mmap_entry
} __attribute__((packed));
+/* Helper for preboot. */
+static int fill_hook (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type, void *data)
+{
+ struct grub_e820_mmap_entry **hookmmapcur = data;
+ grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type);
+ (*hookmmapcur)->addr = addr;
+ (*hookmmapcur)->len = size;
+ (*hookmmapcur)->type = type;
+ (*hookmmapcur)++;
+ return 0;
+}
+
static grub_err_t
preboot (int noreturn __attribute__ ((unused)))
{
struct grub_e820_mmap_entry *hookmmap, *hookmmapcur;
- auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
- grub_uint32_t);
- int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type);
- hookmmapcur->addr = addr;
- hookmmapcur->len = size;
- hookmmapcur->type = type;
- hookmmapcur++;
- return 0;
- }
if (! hooktarget)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
@@ -77,7 +78,7 @@ preboot (int noreturn __attribute__ ((unused)))
((grub_uint8_t *) hooktarget + (&grub_machine_mmaphook_end
- &grub_machine_mmaphook_start));
- grub_mmap_iterate (fill_hook);
+ grub_mmap_iterate (fill_hook, &hookmmapcur);
grub_machine_mmaphook_mmap_num = hookmmapcur - hookmmap;
grub_machine_mmaphook_kblow = grub_mmap_get_lower () >> 10;
@@ -123,6 +124,17 @@ preboot_rest (void)
return GRUB_ERR_NONE;
}
+/* Helper for malloc_hook. */
+static int
+count_hook (grub_uint64_t addr __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
+ grub_memory_type_t type __attribute__ ((unused)), void *data)
+{
+ int *regcount = data;
+ (*regcount)++;
+ return 0;
+}
+
static grub_err_t
malloc_hook (void)
{
@@ -131,22 +143,13 @@ malloc_hook (void)
static int slots_available = 0;
int hooksize;
int regcount = 0;
- auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
- grub_uint32_t);
- int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
- grub_uint64_t size __attribute__ ((unused)),
- grub_memory_type_t type __attribute__ ((unused)))
- {
- regcount++;
- return 0;
- }
if (reentry)
return GRUB_ERR_NONE;
grub_dprintf ("mmap", "registering\n");
- grub_mmap_iterate (count_hook);
+ grub_mmap_iterate (count_hook, &regcount);
/* Mapping hook itself may introduce up to 2 additional regions. */
regcount += 2;
diff --git a/grub-core/mmap/i386/uppermem.c b/grub-core/mmap/i386/uppermem.c
index 2aa4301..bd8b429 100644
--- a/grub-core/mmap/i386/uppermem.c
+++ b/grub-core/mmap/i386/uppermem.c
@@ -22,68 +22,73 @@
#include <grub/mm.h>
#include <grub/misc.h>
+/* Helper for grub_mmap_get_lower. */
+static int
+lower_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
+{
+ grub_uint64_t *lower = data;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ if (addr == 0)
+ *lower = size;
+ return 0;
+}
+
grub_uint64_t
grub_mmap_get_lower (void)
{
grub_uint64_t lower = 0;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
- if (addr == 0)
- lower = size;
- return 0;
- }
-
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (lower_hook, &lower);
if (lower > 0x100000)
lower = 0x100000;
return lower;
}
+/* Helper for grub_mmap_get_upper. */
+static int
+upper_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
+{
+ grub_uint64_t *upper = data;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ if (addr <= 0x100000 && addr + size > 0x100000)
+ *upper = addr + size - 0x100000;
+ return 0;
+}
+
grub_uint64_t
grub_mmap_get_upper (void)
{
grub_uint64_t upper = 0;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
- if (addr <= 0x100000 && addr + size > 0x100000)
- upper = addr + size - 0x100000;
- return 0;
- }
-
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (upper_hook, &upper);
return upper;
}
+/* Helper for grub_mmap_get_post64. */
+static int
+post64_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
+{
+ grub_uint64_t *post64 = data;
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ if (addr <= 0x4000000 && addr + size > 0x4000000)
+ *post64 = addr + size - 0x4000000;
+ return 0;
+}
+
/* Count the continuous bytes after 64 MiB. */
grub_uint64_t
grub_mmap_get_post64 (void)
{
grub_uint64_t post64 = 0;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
- if (addr <= 0x4000000 && addr + size > 0x4000000)
- post64 = addr + size - 0x4000000;
- return 0;
- }
-
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (post64_hook, &post64);
return post64;
}
diff --git a/grub-core/mmap/mips/uppermem.c b/grub-core/mmap/mips/uppermem.c
index 8326185..a980e07 100644
--- a/grub-core/mmap/mips/uppermem.c
+++ b/grub-core/mmap/mips/uppermem.c
@@ -22,47 +22,51 @@
#include <grub/misc.h>
#include <grub/cpu/memory.h>
+/* Helper for grub_mmap_get_lower. */
+static int
+lower_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
+{
+ grub_uint64_t *lower = data;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ if (addr == 0)
+ *lower = size;
+ return 0;
+}
+
grub_uint64_t
grub_mmap_get_lower (void)
{
grub_uint64_t lower = 0;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
- if (addr == 0)
- lower = size;
- return 0;
- }
-
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (lower_hook, &lower);
if (lower > GRUB_ARCH_LOWMEMMAXSIZE)
lower = GRUB_ARCH_LOWMEMMAXSIZE;
return lower;
}
+/* Helper for grub_mmap_get_upper. */
+static int
+upper_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
+{
+ grub_uint64_t *upper = data;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+ if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size
+ > GRUB_ARCH_HIGHMEMPSTART)
+ *upper = addr + size - GRUB_ARCH_HIGHMEMPSTART;
+ return 0;
+}
+
grub_uint64_t
grub_mmap_get_upper (void)
{
grub_uint64_t upper = 0;
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
- grub_memory_type_t type)
- {
- if (type != GRUB_MEMORY_AVAILABLE)
- return 0;
- if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size
- > GRUB_ARCH_HIGHMEMPSTART)
- upper = addr + size - GRUB_ARCH_HIGHMEMPSTART;
- return 0;
- }
-
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (upper_hook, &upper);
return upper;
}
diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
index 0b734dd..40ffb2e 100644
--- a/grub-core/mmap/mmap.c
+++ b/grub-core/mmap/mmap.c
@@ -35,43 +35,90 @@ static int curhandle = 1;
#endif
-grub_err_t
-grub_mmap_iterate (grub_memory_hook_t hook)
+/* If same page is used by multiple types it's resolved
+ according to priority:
+ 1 - free memory
+ 2 - memory usable by firmware-aware code
+ 3 - unusable memory
+ 4 - a range deliberately empty
+*/
+static const int priority[] =
+{
+ [GRUB_MEMORY_AVAILABLE] = 1,
+ [GRUB_MEMORY_RESERVED] = 3,
+ [GRUB_MEMORY_ACPI] = 2,
+ [GRUB_MEMORY_CODE] = 3,
+ [GRUB_MEMORY_NVS] = 3,
+ [GRUB_MEMORY_HOLE] = 4,
+};
+
+/* Scanline events. */
+struct grub_mmap_scan
+{
+ /* At which memory address. */
+ grub_uint64_t pos;
+ /* 0 = region starts, 1 = region ends. */
+ int type;
+ /* Which type of memory region? */
+ int memtype;
+};
+
+/* Context for grub_mmap_iterate. */
+struct grub_mmap_iterate_ctx
+{
+ struct grub_mmap_scan *scanline_events;
+ int i;
+};
+
+/* Helper for grub_mmap_iterate. */
+static int
+count_hook (grub_uint64_t addr __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
+ grub_memory_type_t type __attribute__ ((unused)), void *data)
+{
+ int *mmap_num = data;
+
+ (*mmap_num)++;
+ return 0;
+}
+
+/* Helper for grub_mmap_iterate. */
+static int
+fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
{
+ struct grub_mmap_iterate_ctx *ctx = data;
+ ctx->scanline_events[ctx->i].pos = addr;
+ ctx->scanline_events[ctx->i].type = 0;
+ if (type < ARRAY_SIZE (priority) && priority[type])
+ ctx->scanline_events[ctx->i].memtype = type;
+ else
+ {
+ grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n",
+ type);
+ ctx->scanline_events[ctx->i].memtype = GRUB_MEMORY_RESERVED;
+ }
+ ctx->i++;
+
+ ctx->scanline_events[ctx->i].pos = addr + size;
+ ctx->scanline_events[ctx->i].type = 1;
+ ctx->scanline_events[ctx->i].memtype =
+ ctx->scanline_events[ctx->i - 1].memtype;
+ ctx->i++;
+
+ return 0;
+}
+
+grub_err_t
+grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+{
/* This function resolves overlapping regions and sorts the memory map.
It uses scanline (sweeping) algorithm.
*/
- /* If same page is used by multiple types it's resolved
- according to priority:
- 1 - free memory
- 2 - memory usable by firmware-aware code
- 3 - unusable memory
- 4 - a range deliberately empty
- */
- int priority[] =
- {
- [GRUB_MEMORY_AVAILABLE] = 1,
- [GRUB_MEMORY_RESERVED] = 3,
- [GRUB_MEMORY_ACPI] = 2,
- [GRUB_MEMORY_CODE] = 3,
- [GRUB_MEMORY_NVS] = 3,
- [GRUB_MEMORY_HOLE] = 4,
- };
-
+ struct grub_mmap_iterate_ctx ctx;
int i, done;
- /* Scanline events. */
- struct grub_mmap_scan
- {
- /* At which memory address. */
- grub_uint64_t pos;
- /* 0 = region starts, 1 = region ends. */
- int type;
- /* Which type of memory region? */
- int memtype;
- };
- struct grub_mmap_scan *scanline_events;
struct grub_mmap_scan t;
/* Previous scanline event. */
@@ -88,42 +135,6 @@ grub_mmap_iterate (grub_memory_hook_t hook)
struct grub_mmap_region *cur;
#endif
- auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
- grub_uint32_t);
- int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
- grub_uint64_t size __attribute__ ((unused)),
- grub_memory_type_t type __attribute__ ((unused)))
- {
- mmap_num++;
- return 0;
- }
-
- auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
- grub_uint32_t);
- int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
- grub_uint64_t size,
- grub_memory_type_t type)
- {
- scanline_events[i].pos = addr;
- scanline_events[i].type = 0;
- if (type < ARRAY_SIZE (priority) && priority[type])
- scanline_events[i].memtype = type;
- else
- {
- grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n",
- type);
- scanline_events[i].memtype = GRUB_MEMORY_RESERVED;
- }
- i++;
-
- scanline_events[i].pos = addr + size;
- scanline_events[i].type = 1;
- scanline_events[i].memtype = scanline_events[i - 1].memtype;
- i++;
-
- return 0;
- }
-
mmap_num = 0;
#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
@@ -131,37 +142,38 @@ grub_mmap_iterate (grub_memory_hook_t hook)
mmap_num++;
#endif
- grub_machine_mmap_iterate (count_hook);
+ grub_machine_mmap_iterate (count_hook, &mmap_num);
/* Initialize variables. */
grub_memset (present, 0, sizeof (present));
- scanline_events = (struct grub_mmap_scan *)
+ ctx.scanline_events = (struct grub_mmap_scan *)
grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num);
- if (! scanline_events)
+ if (! ctx.scanline_events)
return grub_errno;
- i = 0;
+ ctx.i = 0;
#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
/* Register scanline events. */
for (cur = grub_mmap_overlays; cur; cur = cur->next)
{
- scanline_events[i].pos = cur->start;
- scanline_events[i].type = 0;
+ ctx.scanline_events[ctx.i].pos = cur->start;
+ ctx.scanline_events[ctx.i].type = 0;
if (cur->type < ARRAY_SIZE (priority) && priority[cur->type])
- scanline_events[i].memtype = cur->type;
+ ctx.scanline_events[ctx.i].memtype = cur->type;
else
- scanline_events[i].memtype = GRUB_MEMORY_RESERVED;
- i++;
-
- scanline_events[i].pos = cur->end;
- scanline_events[i].type = 1;
- scanline_events[i].memtype = scanline_events[i - 1].memtype;
- i++;
+ ctx.scanline_events[ctx.i].memtype = GRUB_MEMORY_RESERVED;
+ ctx.i++;
+
+ ctx.scanline_events[ctx.i].pos = cur->end;
+ ctx.scanline_events[ctx.i].type = 1;
+ ctx.scanline_events[ctx.i].memtype =
+ ctx.scanline_events[ctx.i - 1].memtype;
+ ctx.i++;
}
#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */
- grub_machine_mmap_iterate (fill_hook);
+ grub_machine_mmap_iterate (fill_hook, &ctx);
/* Primitive bubble sort. It has complexity O(n^2) but since we're
unlikely to have more than 100 chunks it's probably one of the
@@ -171,28 +183,28 @@ grub_mmap_iterate (grub_memory_hook_t hook)
{
done = 0;
for (i = 0; i < 2 * mmap_num - 1; i++)
- if (scanline_events[i + 1].pos < scanline_events[i].pos
- || (scanline_events[i + 1].pos == scanline_events[i].pos
- && scanline_events[i + 1].type == 0
- && scanline_events[i].type == 1))
+ if (ctx.scanline_events[i + 1].pos < ctx.scanline_events[i].pos
+ || (ctx.scanline_events[i + 1].pos == ctx.scanline_events[i].pos
+ && ctx.scanline_events[i + 1].type == 0
+ && ctx.scanline_events[i].type == 1))
{
- t = scanline_events[i + 1];
- scanline_events[i + 1] = scanline_events[i];
- scanline_events[i] = t;
+ t = ctx.scanline_events[i + 1];
+ ctx.scanline_events[i + 1] = ctx.scanline_events[i];
+ ctx.scanline_events[i] = t;
done = 1;
}
}
- lastaddr = scanline_events[0].pos;
- lasttype = scanline_events[0].memtype;
+ lastaddr = ctx.scanline_events[0].pos;
+ lasttype = ctx.scanline_events[0].memtype;
for (i = 0; i < 2 * mmap_num; i++)
{
unsigned k;
/* Process event. */
- if (scanline_events[i].type)
- present[scanline_events[i].memtype]--;
+ if (ctx.scanline_events[i].type)
+ present[ctx.scanline_events[i].memtype]--;
else
- present[scanline_events[i].memtype]++;
+ present[ctx.scanline_events[i].memtype]++;
/* Determine current region type. */
curtype = -1;
@@ -202,12 +214,13 @@ grub_mmap_iterate (grub_memory_hook_t hook)
/* Announce region to the hook if necessary. */
if ((curtype == -1 || curtype != lasttype)
- && lastaddr != scanline_events[i].pos
+ && lastaddr != ctx.scanline_events[i].pos
&& lasttype != -1
&& lasttype != GRUB_MEMORY_HOLE
- && hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype))
+ && hook (lastaddr, ctx.scanline_events[i].pos - lastaddr, lasttype,
+ hook_data))
{
- grub_free (scanline_events);
+ grub_free (ctx.scanline_events);
return GRUB_ERR_NONE;
}
@@ -215,11 +228,11 @@ grub_mmap_iterate (grub_memory_hook_t hook)
if (curtype == -1 || curtype != lasttype)
{
lasttype = curtype;
- lastaddr = scanline_events[i].pos;
+ lastaddr = ctx.scanline_events[i].pos;
}
}
- grub_free (scanline_events);
+ grub_free (ctx.scanline_events);
return GRUB_ERR_NONE;
}
@@ -280,19 +293,23 @@ grub_mmap_unregister (int handle)
#define CHUNK_SIZE 0x400
+struct badram_entry {
+ grub_uint64_t addr, mask;
+};
+
static inline grub_uint64_t
-fill_mask (grub_uint64_t addr, grub_uint64_t mask, grub_uint64_t iterator)
+fill_mask (struct badram_entry *entry, grub_uint64_t iterator)
{
int i, j;
- grub_uint64_t ret = (addr & mask);
+ grub_uint64_t ret = (entry->addr & entry->mask);
/* Find first fixed bit. */
for (i = 0; i < 64; i++)
- if ((mask & (1ULL << i)) != 0)
+ if ((entry->mask & (1ULL << i)) != 0)
break;
j = 0;
for (; i < 64; i++)
- if ((mask & (1ULL << i)) == 0)
+ if ((entry->mask & (1ULL << i)) == 0)
{
if ((iterator & (1ULL << j)) != 0)
ret |= 1ULL << i;
@@ -301,64 +318,64 @@ fill_mask (grub_uint64_t addr, grub_uint64_t mask, grub_uint64_t iterator)
return ret;
}
+/* Helper for grub_cmd_badram. */
+static int
+badram_iter (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type __attribute__ ((unused)), void *data)
+{
+ struct badram_entry *entry = data;
+ grub_uint64_t iterator, low, high, cur;
+ int tail, var;
+ int i;
+ grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr,
+ (unsigned long long) size);
+
+ /* How many trailing zeros? */
+ for (tail = 0; ! (entry->mask & (1ULL << tail)); tail++);
+
+ /* How many zeros in mask? */
+ var = 0;
+ for (i = 0; i < 64; i++)
+ if (! (entry->mask & (1ULL << i)))
+ var++;
+
+ if (fill_mask (entry, 0) >= addr)
+ iterator = 0;
+ else
+ {
+ low = 0;
+ high = ~0ULL;
+ /* Find starting value. Keep low and high such that
+ fill_mask (low) < addr and fill_mask (high) >= addr;
+ */
+ while (high - low > 1)
+ {
+ cur = (low + high) / 2;
+ if (fill_mask (entry, cur) >= addr)
+ high = cur;
+ else
+ low = cur;
+ }
+ iterator = high;
+ }
+
+ for (; iterator < (1ULL << (var - tail))
+ && (cur = fill_mask (entry, iterator)) < addr + size;
+ iterator++)
+ {
+ grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
+ (unsigned long long) cur, (1ULL << tail));
+ grub_mmap_register (cur, (1ULL << tail), GRUB_MEMORY_HOLE);
+ }
+ return 0;
+}
+
static grub_err_t
grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
char * str;
- grub_uint64_t badaddr, badmask;
-
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
- grub_uint64_t size,
- grub_memory_type_t type __attribute__ ((unused)))
- {
- grub_uint64_t iterator, low, high, cur;
- int tail, var;
- int i;
- grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr,
- (unsigned long long) size);
-
- /* How many trailing zeros? */
- for (tail = 0; ! (badmask & (1ULL << tail)); tail++);
-
- /* How many zeros in mask? */
- var = 0;
- for (i = 0; i < 64; i++)
- if (! (badmask & (1ULL << i)))
- var++;
-
- if (fill_mask (badaddr, badmask, 0) >= addr)
- iterator = 0;
- else
- {
- low = 0;
- high = ~0ULL;
- /* Find starting value. Keep low and high such that
- fill_mask (low) < addr and fill_mask (high) >= addr;
- */
- while (high - low > 1)
- {
- cur = (low + high) / 2;
- if (fill_mask (badaddr, badmask, cur) >= addr)
- high = cur;
- else
- low = cur;
- }
- iterator = high;
- }
-
- for (; iterator < (1ULL << (var - tail))
- && (cur = fill_mask (badaddr, badmask, iterator)) < addr + size;
- iterator++)
- {
- grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
- (unsigned long long) cur, (1ULL << tail));
- grub_mmap_register (cur, (1ULL << tail), GRUB_MEMORY_HOLE);
- }
- return 0;
- }
+ struct badram_entry entry;
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
@@ -370,10 +387,10 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
while (1)
{
/* Parse address and mask. */
- badaddr = grub_strtoull (str, &str, 16);
+ entry.addr = grub_strtoull (str, &str, 16);
if (*str == ',')
str++;
- badmask = grub_strtoull (str, &str, 16);
+ entry.mask = grub_strtoull (str, &str, 16);
if (*str == ',')
str++;
@@ -385,12 +402,13 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
/* When part of a page is tainted, we discard the whole of it. There's
no point in providing sub-page chunks. */
- badmask &= ~(CHUNK_SIZE - 1);
+ entry.mask &= ~(CHUNK_SIZE - 1);
grub_dprintf ("badram", "badram %llx:%llx\n",
- (unsigned long long) badaddr, (unsigned long long) badmask);
+ (unsigned long long) entry.addr,
+ (unsigned long long) entry.mask);
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (badram_iter, &entry);
}
}
@@ -416,44 +434,48 @@ parsemem (const char *str)
return ret;
}
-static grub_err_t
-grub_cmd_cutmem (grub_command_t cmd __attribute__ ((unused)),
- int argc, char **args)
-{
+struct cutmem_range {
grub_uint64_t from, to;
+};
- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
- grub_memory_type_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
- grub_uint64_t size,
- grub_memory_type_t type __attribute__ ((unused)))
- {
- grub_uint64_t end = addr + size;
-
- if (addr <= from)
- addr = from;
- if (end >= to)
- end = to;
+/* Helper for grub_cmd_cutmem. */
+static int
+cutmem_iter (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type __attribute__ ((unused)), void *data)
+{
+ struct cutmem_range *range = data;
+ grub_uint64_t end = addr + size;
- if (end <= addr)
- return 0;
+ if (addr <= range->from)
+ addr = range->from;
+ if (end >= range->to)
+ end = range->to;
- grub_mmap_register (addr, end - addr, GRUB_MEMORY_HOLE);
+ if (end <= addr)
return 0;
- }
+
+ grub_mmap_register (addr, end - addr, GRUB_MEMORY_HOLE);
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_cutmem (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ struct cutmem_range range;
if (argc != 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
- from = parsemem (args[0]);
+ range.from = parsemem (args[0]);
if (grub_errno)
return grub_errno;
- to = parsemem (args[1]);
+ range.to = parsemem (args[1]);
if (grub_errno)
return grub_errno;
- grub_mmap_iterate (hook);
+ grub_mmap_iterate (cutmem_iter, &range);
return GRUB_ERR_NONE;
}
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index f36d4cd..33f860a 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -140,7 +140,7 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask)
break;
/* If you need any other options please contact GRUB
- developpement team. */
+ development team. */
}
ptr += taglength;
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 01c5d32..aebbe4b 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -1253,8 +1253,8 @@ grub_net_open_real (const char *name)
static grub_err_t
grub_net_fs_dir (grub_device_t device, const char *path __attribute__ ((unused)),
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info) __attribute__ ((unused)))
+ grub_fs_dir_hook_t hook __attribute__ ((unused)),
+ void *hook_data __attribute__ ((unused)))
{
if (!device->net)
return grub_error (GRUB_ERR_BUG, "invalid net device");
diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
index 25593ce..bd9fbf4 100644
--- a/grub-core/normal/charset.c
+++ b/grub-core/normal/charset.c
@@ -513,7 +513,10 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
struct grub_unicode_glyph *visual,
grub_size_t visual_len, unsigned *levels,
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
- grub_size_t maxwidth, grub_size_t startwidth)
+ grub_size_t maxwidth, grub_size_t startwidth,
+ grub_uint32_t contchar,
+ struct grub_term_pos *pos, int primitive_wrap,
+ grub_size_t log_end)
{
struct grub_unicode_glyph *outptr = visual_out;
unsigned line_start = 0;
@@ -521,17 +524,30 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
unsigned k;
grub_ssize_t last_space = -1;
grub_ssize_t last_space_width = 0;
+ int lines = 0;
auto void revert (unsigned start, unsigned end);
void revert (unsigned start, unsigned end)
{
struct grub_unicode_glyph t;
unsigned i, tl;
+ int a, b;
+ if (pos)
+ {
+ a = pos[visual[start].orig_pos].x;
+ b = pos[visual[end].orig_pos].x;
+ }
for (i = 0; i < (end - start) / 2 + 1; i++)
{
t = visual[start + i];
visual[start + i] = visual[end - i];
visual[end - i] = t;
+
+ if (pos)
+ {
+ pos[visual[start + i].orig_pos].x = a + b - pos[visual[start + i].orig_pos].x;
+ pos[visual[end - i].orig_pos].x = a + b - pos[visual[end - i].orig_pos].x;
+ }
tl = levels[start + i];
levels[start + i] = levels[end - i];
levels[end - i] = tl;
@@ -545,11 +561,27 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
{
grub_ssize_t last_width = 0;
+
+ if (pos && k != visual_len)
+ {
+ pos[visual[k].orig_pos].x = line_width;
+ pos[visual[k].orig_pos].y = lines;
+ pos[visual[k].orig_pos].valid = 1;
+ }
+
+ if (k == visual_len && pos)
+ {
+ pos[log_end].x = line_width;
+ pos[log_end].y = lines;
+ pos[log_end].valid = 1;
+ }
+
if (getcharwidth && k != visual_len)
line_width += last_width = getcharwidth (&visual[k]);
if (k != visual_len && (visual[k].base == ' '
- || visual[k].base == '\t'))
+ || visual[k].base == '\t')
+ && !primitive_wrap)
{
last_space = k;
last_space_width = line_width;
@@ -561,9 +593,12 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
unsigned min_odd_level = 0xffffffff;
unsigned max_level = 0;
+ lines++;
+
if (k != visual_len && last_space > (signed) line_start)
k = last_space;
- else if (k != visual_len && line_start == 0 && startwidth != 0)
+ else if (k != visual_len && line_start == 0 && startwidth != 0
+ && !primitive_wrap)
{
k = 0;
last_space_width = startwidth;
@@ -685,6 +720,12 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
outptr += k - line_start;
if (k != visual_len)
{
+ if (contchar)
+ {
+ grub_memset (outptr, 0, sizeof (visual[0]));
+ outptr->base = contchar;
+ outptr++;
+ }
grub_memset (outptr, 0, sizeof (visual[0]));
outptr->base = '\n';
outptr++;
@@ -695,6 +736,11 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
line_start = k;
line_width -= last_space_width;
+ if (pos && k != visual_len)
+ {
+ pos[visual[k].orig_pos].x = 0;
+ pos[visual[k].orig_pos].y = lines;
+ }
}
}
@@ -707,7 +753,11 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
grub_size_t logical_len,
struct grub_unicode_glyph *visual_out,
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
- grub_size_t maxwidth, grub_size_t startwidth)
+ grub_size_t maxwidth, grub_size_t startwidth,
+ grub_uint32_t contchar,
+ struct grub_term_pos *pos,
+ int primitive_wrap,
+ grub_size_t log_end)
{
enum grub_bidi_type type = GRUB_BIDI_TYPE_L;
enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L};
@@ -832,7 +882,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
p = grub_unicode_aglomerate_comb (lptr, logical + logical_len - lptr,
&visual[visual_len]);
-
+ visual[visual_len].orig_pos = lptr - logical;
type = get_bidi_type (visual[visual_len].base);
switch (type)
{
@@ -1066,7 +1116,8 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
{
grub_ssize_t ret;
ret = bidi_line_wrap (visual_out, visual, visual_len, levels,
- getcharwidth, maxwidth, startwidth);
+ getcharwidth, maxwidth, startwidth, contchar,
+ pos, primitive_wrap, log_end);
grub_free (levels);
grub_free (visual);
return ret;
@@ -1078,11 +1129,12 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical,
grub_size_t logical_len,
struct grub_unicode_glyph **visual_out,
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
- grub_size_t max_length, grub_size_t startwidth)
+ grub_size_t max_length, grub_size_t startwidth,
+ grub_uint32_t contchar, struct grub_term_pos *pos, int primitive_wrap)
{
const grub_uint32_t *line_start = logical, *ptr;
struct grub_unicode_glyph *visual_ptr;
- *visual_out = visual_ptr = grub_malloc (2 * sizeof (visual_ptr[0])
+ *visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0])
* logical_len);
if (!visual_ptr)
return -1;
@@ -1096,7 +1148,11 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical,
visual_ptr,
getcharwidth,
max_length,
- startwidth);
+ startwidth,
+ contchar,
+ pos,
+ primitive_wrap,
+ logical_len);
startwidth = 0;
if (ret < 0)
@@ -1188,3 +1244,27 @@ grub_unicode_get_comb_start (const grub_uint32_t *str,
return str;
}
+const grub_uint32_t *
+grub_unicode_get_comb_end (const grub_uint32_t *end,
+ const grub_uint32_t *cur)
+{
+ const grub_uint32_t *ptr;
+ for (ptr = cur; ptr < end; ptr++)
+ {
+ if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1
+ && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16)
+ continue;
+
+ if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17
+ && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256)
+ continue;
+
+ enum grub_comb_type comb_type;
+ comb_type = grub_unicode_get_comb_type (*ptr);
+ if (comb_type)
+ continue;
+ return ptr;
+ }
+ return end;
+}
+
diff --git a/grub-core/normal/color.c b/grub-core/normal/color.c
index 06f1a87..c265423 100644
--- a/grub-core/normal/color.c
+++ b/grub-core/normal/color.c
@@ -106,8 +106,6 @@ free_and_return:
return result;
}
-static grub_uint8_t color_normal, color_highlight;
-
static void
set_colors (void)
{
@@ -115,9 +113,6 @@ set_colors (void)
FOR_ACTIVE_TERM_OUTPUTS(term)
{
- /* Reloads terminal `normal' and `highlight' colors. */
- grub_term_setcolor (term, color_normal, color_highlight);
-
/* Propagates `normal' color to terminal current color. */
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
}
@@ -128,7 +123,7 @@ char *
grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
{
- if (grub_parse_color_name_pair (&color_normal, val))
+ if (grub_parse_color_name_pair (&grub_term_normal_color, val))
return NULL;
set_colors ();
@@ -141,7 +136,7 @@ char *
grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
{
- if (grub_parse_color_name_pair (&color_highlight, val))
+ if (grub_parse_color_name_pair (&grub_term_highlight_color, val))
return NULL;
set_colors ();
diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c
index cae78f1..71c083c 100644
--- a/grub-core/normal/completion.c
+++ b/grub-core/normal/completion.c
@@ -99,7 +99,8 @@ add_completion (const char *completion, const char *extra,
}
static int
-iterate_partition (grub_disk_t disk, const grub_partition_t p)
+iterate_partition (grub_disk_t disk, const grub_partition_t p,
+ void *data __attribute__ ((unused)))
{
const char *disk_name = disk->name;
char *name;
@@ -122,7 +123,8 @@ iterate_partition (grub_disk_t disk, const grub_partition_t p)
}
static int
-iterate_dir (const char *filename, const struct grub_dirhook_info *info)
+iterate_dir (const char *filename, const struct grub_dirhook_info *info,
+ void *data __attribute__ ((unused)))
{
if (! info->dir)
{
@@ -154,7 +156,7 @@ iterate_dir (const char *filename, const struct grub_dirhook_info *info)
}
static int
-iterate_dev (const char *devname)
+iterate_dev (const char *devname, void *data __attribute__ ((unused)))
{
grub_device_t dev;
@@ -180,7 +182,7 @@ iterate_dev (const char *devname)
}
if (dev->disk)
- if (grub_partition_iterate (dev->disk, iterate_partition))
+ if (grub_partition_iterate (dev->disk, iterate_partition, NULL))
{
grub_device_close (dev);
return 1;
@@ -213,7 +215,7 @@ complete_device (void)
if (! p)
{
/* Complete the disk part. */
- if (grub_disk_dev_iterate (iterate_dev))
+ if (grub_disk_dev_iterate (iterate_dev, NULL))
return 1;
}
else
@@ -228,7 +230,7 @@ complete_device (void)
{
if (dev->disk)
{
- if (grub_partition_iterate (dev->disk, iterate_partition))
+ if (grub_partition_iterate (dev->disk, iterate_partition, NULL))
{
grub_device_close (dev);
return 1;
@@ -294,7 +296,7 @@ complete_file (void)
dirfile[1] = '\0';
/* Iterate the directory. */
- (fs->dir) (dev, dir, iterate_dir);
+ (fs->dir) (dev, dir, iterate_dir, NULL);
grub_free (dir);
@@ -418,7 +420,7 @@ grub_normal_do_completion (char *buf, int *restore,
*restore = 1;
- if (grub_parser_split_cmdline (buf, 0, &argc, &argv))
+ if (grub_parser_split_cmdline (buf, 0, 0, &argc, &argv))
return 0;
if (argc == 0)
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index 13473ec..07f337d 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -134,33 +134,37 @@ grub_normal_free_menu (grub_menu_t menu)
grub_env_unset_menu ();
}
-static grub_menu_t
-read_config_file (const char *config)
+/* Helper for read_config_file. */
+static grub_err_t
+read_config_file_getline (char **line, int cont __attribute__ ((unused)),
+ void *data)
{
- grub_file_t file;
- const char *old_file, *old_dir;
- char *config_dir, *ptr = 0;
+ grub_file_t file = data;
- auto grub_err_t getline (char **line, int cont);
- grub_err_t getline (char **line, int cont __attribute__ ((unused)))
+ while (1)
{
- while (1)
- {
- char *buf;
+ char *buf;
- *line = buf = grub_file_getline (file);
- if (! buf)
- return grub_errno;
+ *line = buf = grub_file_getline (file);
+ if (! buf)
+ return grub_errno;
- if (buf[0] == '#')
- grub_free (*line);
- else
- break;
- }
-
- return GRUB_ERR_NONE;
+ if (buf[0] == '#')
+ grub_free (*line);
+ else
+ break;
}
+ return GRUB_ERR_NONE;
+}
+
+static grub_menu_t
+read_config_file (const char *config)
+{
+ grub_file_t file;
+ const char *old_file, *old_dir;
+ char *config_dir, *ptr = 0;
+
grub_menu_t newmenu;
newmenu = grub_env_get_menu ();
@@ -199,10 +203,10 @@ read_config_file (const char *config)
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
- if ((getline (&line, 0)) || (! line))
+ if ((read_config_file_getline (&line, 0, file)) || (! line))
break;
- grub_normal_parse_line (line, getline);
+ grub_normal_parse_line (line, read_config_file_getline, file);
grub_free (line);
}
@@ -427,7 +431,8 @@ grub_normal_read_line_real (char **line, int cont, int nested)
}
static grub_err_t
-grub_normal_read_line (char **line, int cont)
+grub_normal_read_line (char **line, int cont,
+ void *data __attribute__ ((unused)))
{
return grub_normal_read_line_real (line, cont, 0);
}
@@ -463,7 +468,7 @@ grub_cmdline_run (int nested)
if (! line)
break;
- grub_normal_parse_line (line, grub_normal_read_line);
+ grub_normal_parse_line (line, grub_normal_read_line, NULL);
grub_free (line);
}
}
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
index 8e2b4da..7cd67f3 100644
--- a/grub-core/normal/menu_entry.c
+++ b/grub-core/normal/menu_entry.c
@@ -43,15 +43,12 @@ struct line
int len;
/* The maximum length of the line. */
int max_len;
+ struct grub_term_pos **pos;
};
struct per_term_screen
{
struct grub_term_output *term;
- /* The X coordinate. */
- int x;
- /* The Y coordinate. */
- int y;
int y_line_start;
/* Number of entries. */
int num_entries;
@@ -90,13 +87,18 @@ static int completion_type;
/* Initialize a line. */
static int
-init_line (struct line *linep)
+init_line (struct screen *screen, struct line *linep)
{
linep->len = 0;
linep->max_len = 80;
linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0]));
- if (! linep->buf)
- return 0;
+ linep->pos = grub_zalloc (screen->nterms * sizeof (linep->pos[0]));
+ if (! linep->buf || !linep->pos)
+ {
+ grub_free (linep->buf);
+ grub_free (linep->pos);
+ return 0;
+ }
return 1;
}
@@ -126,93 +128,16 @@ get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
}
static void
-advance (struct screen *screen)
-{
- unsigned i;
- struct grub_unicode_glyph glyph;
-
- screen->column += grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column,
- screen->lines[screen->line].len - screen->column,
- &glyph);
-
- for (i = 0; i < screen->nterms; i++)
- {
- grub_ssize_t width;
- width = grub_term_getcharwidth (screen->terms[i].term, &glyph);
- screen->terms[i].x += width;
- if (screen->terms[i].x
- == grub_term_entry_width (screen->terms[i].term))
- {
- screen->terms[i].x = 0;
- screen->terms[i].y++;
- }
- if (screen->terms[i].x
- > grub_term_entry_width (screen->terms[i].term))
- {
- screen->terms[i].x = width;
- screen->terms[i].y++;
- }
- }
- grub_free (glyph.combining);
-}
-
-static void
advance_to (struct screen *screen, int c)
{
if (c > screen->lines[screen->line].len)
c = screen->lines[screen->line].len;
- while (screen->column < c)
- advance (screen);
-}
-
-/* Print a line. */
-static int
-print_line (struct line *linep, int offset, int y,
- struct per_term_screen *term_screen, int dry_run)
-{
- int x;
- int i;
-
- grub_term_gotoxy (term_screen->term,
- GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
- y + GRUB_TERM_FIRST_ENTRY_Y);
-
- x = 0;
- for (i = 0; i + offset < (int) linep->len;)
- {
- grub_ssize_t width;
- grub_size_t delta = 0;
- struct grub_unicode_glyph glyph;
-
- delta = grub_unicode_aglomerate_comb (linep->buf + offset + i,
- linep->len - offset - i,
- &glyph);
- width = grub_term_getcharwidth (term_screen->term, &glyph);
- grub_free (glyph.combining);
-
- if (x + width > grub_term_entry_width (term_screen->term) && x != 0)
- break;
- x += width;
- i += delta;
- }
-
- if (dry_run)
- return i;
-
- grub_print_ucs4 (linep->buf + offset,
- linep->buf + offset + i, 0, 0, term_screen->term);
-
- if (i + offset != linep->len)
- grub_putcode ('\\', term_screen->term);
- else
- {
- for (;
- x <= (int) grub_term_entry_width (term_screen->term);
- x++)
- grub_putcode (' ', term_screen->term);
- }
- return i;
+ screen->column = grub_unicode_get_comb_end (screen->lines[screen->line].buf
+ + screen->lines[screen->line].len,
+ screen->lines[screen->line].buf
+ + c)
+ - screen->lines[screen->line].buf;
}
/* Print an empty line. */
@@ -225,7 +150,7 @@ print_empty_line (int y, struct per_term_screen *term_screen)
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
y + GRUB_TERM_FIRST_ENTRY_Y);
- for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++)
+ for (i = 0; i < grub_term_entry_width (term_screen->term); i++)
grub_putcode (' ', term_screen->term);
}
@@ -261,7 +186,7 @@ print_down (int flag, struct per_term_screen *term_screen)
/* Draw the lines of the screen SCREEN. */
static void
update_screen (struct screen *screen, struct per_term_screen *term_screen,
- int region_start, int region_column,
+ int region_start, int region_column __attribute__ ((unused)),
int up, int down, enum update_mode mode)
{
int up_flag = 0;
@@ -270,19 +195,26 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
int i;
struct line *linep;
+ y = term_screen->y_line_start;
+ linep = screen->lines;
+
+ for (i = 0; i < screen->line; i++, linep++)
+ y += get_logical_num_lines (linep, term_screen);
+ linep = screen->lines + screen->line;
+ y += grub_getstringwidth (linep->buf, linep->buf + screen->column,
+ term_screen->term) / grub_term_entry_width (term_screen->term);
+
/* Check if scrolling is necessary. */
- if (term_screen->y < 0 || term_screen->y >= term_screen->num_entries)
+ if (y < 0 || y >= term_screen->num_entries)
{
int delta;
- if (term_screen->y < 0)
- delta = -term_screen->y;
+ if (y < 0)
+ delta = -y;
else
- delta = term_screen->num_entries - 1 - term_screen->y;
- term_screen->y += delta;
+ delta = term_screen->num_entries - 1 - y;
term_screen->y_line_start += delta;
region_start = 0;
- region_column = 0;
up = 1;
down = 1;
mode = ALL_LINES;
@@ -293,58 +225,81 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
/* Draw lines. This code is tricky, because this must calculate logical
positions. */
y = term_screen->y_line_start;
- i = screen->line;
- linep = screen->lines + i;
- while (y > 0)
- {
- i--;
- linep--;
- y -= get_logical_num_lines (linep, term_screen);
- }
+ i = 0;
+ linep = screen->lines;
+ while (1)
+ {
+ int add;
+ add = get_logical_num_lines (linep, term_screen);
+ if (y + add > 0)
+ break;
+ i++;
+ linep++;
+ y += add;
+ }
if (y < 0 || i > 0)
up_flag = 1;
do
{
- int column;
int off = 0;
- int full_len;
+ struct grub_term_pos **pos;
if (linep >= screen->lines + screen->num_lines)
break;
- full_len = grub_getstringwidth (linep->buf, linep->buf + linep->len,
- term_screen->term);
+ pos = linep->pos + (term_screen - screen->terms);
- for (column = 0;
- column <= full_len
- && y < term_screen->num_entries;
- column += grub_term_entry_width (term_screen->term), y++)
+ if (!*pos)
+ *pos = grub_zalloc ((linep->len + 1) * sizeof (**pos));
+
+ if (i == region_start || linep == screen->lines + screen->line)
+ {
+ int sp;
+ grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
+ + GRUB_TERM_MARGIN + 1, (y < 0 ? 0 : y)
+ + GRUB_TERM_FIRST_ENTRY_Y);
+ grub_print_ucs4_menu (linep->buf,
+ linep->buf + linep->len,
+ GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN
+ + 1,
+ GRUB_TERM_MARGIN
+ + GRUB_TERM_SCROLL_WIDTH + 2,
+ term_screen->term,
+ (y < 0) ? -y : 0,
+ term_screen->num_entries
+ - ((y > 0) ? y : 0), '\\',
+ *pos);
+ sp = grub_term_entry_width (term_screen->term)
+ - (*pos)[linep->len].x;
+ if (sp > 0)
+ grub_print_spaces (term_screen->term, sp);
+ }
+ else if (i > region_start && mode == ALL_LINES)
{
- if (y < 0)
- {
- off += print_line (linep, off, y, term_screen, 1);
- continue;
- }
-
- if (i == region_start)
- {
- if (region_column >= column
- && region_column
- < (column
- + grub_term_entry_width (term_screen->term)))
- off += print_line (linep, off, y, term_screen, 0);
- else if (region_column < column)
- off += print_line (linep, off, y, term_screen, 0);
- else
- off += print_line (linep, off, y, term_screen, 1);
- }
- else if (i > region_start && mode == ALL_LINES)
- off += print_line (linep, off, y, term_screen, 0);
+ int sp;
+ grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
+ + GRUB_TERM_MARGIN + 1, (y < 0 ? 0 : y)
+ + GRUB_TERM_FIRST_ENTRY_Y);
+ grub_print_ucs4_menu (linep->buf,
+ linep->buf + linep->len,
+ GRUB_TERM_LEFT_BORDER_X
+ + GRUB_TERM_MARGIN + 1,
+ GRUB_TERM_MARGIN
+ + GRUB_TERM_SCROLL_WIDTH + 2,
+ term_screen->term,
+ (y < 0) ? -y : 0,
+ term_screen->num_entries
+ - ((y > 0) ? y : 0), '\\',
+ *pos);
+ sp = grub_term_entry_width (term_screen->term)
+ - (*pos)[linep->len].x;
+ if (sp > 0)
+ grub_print_spaces (term_screen->term, sp);
}
-
- if (y == term_screen->num_entries)
+ y += get_logical_num_lines (linep, term_screen);
+ if (y >= term_screen->num_entries)
{
if (off <= linep->len || i + 1 < screen->num_lines)
down_flag = 1;
@@ -367,10 +322,30 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
}
/* Place the cursor. */
- grub_term_gotoxy (term_screen->term,
- GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1
- + term_screen->x,
- GRUB_TERM_FIRST_ENTRY_Y + term_screen->y);
+ if (screen->lines[screen->line].pos[term_screen - screen->terms])
+ {
+ const struct grub_term_pos *cpos;
+ for (cpos = &(screen->lines[screen->line].pos[term_screen - screen->terms])[screen->column];
+ cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0];
+ cpos--)
+ if (cpos->valid)
+ break;
+ y = term_screen->y_line_start;
+ for (i = 0; i < screen->line; i++)
+ y += get_logical_num_lines (screen->lines + i, term_screen);
+ if (cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0])
+ grub_term_gotoxy (term_screen->term,
+ cpos->x + GRUB_TERM_LEFT_BORDER_X
+ + GRUB_TERM_MARGIN + 1,
+ cpos->y + y
+ + GRUB_TERM_FIRST_ENTRY_Y);
+ else
+ grub_term_gotoxy (term_screen->term,
+ GRUB_TERM_LEFT_BORDER_X
+ + GRUB_TERM_MARGIN + 1,
+ y + GRUB_TERM_FIRST_ENTRY_Y);
+
+ }
grub_term_refresh (term_screen->term);
}
@@ -424,7 +399,7 @@ insert_string (struct screen *screen, const char *s, int update)
((screen->num_lines - screen->line - 2)
* sizeof (struct line)));
- if (! init_line (screen->lines + screen->line + 1))
+ if (! init_line (screen, screen->lines + screen->line + 1))
return 0;
/* Fold the line. */
@@ -439,6 +414,11 @@ insert_string (struct screen *screen, const char *s, int update)
current_linep->buf + screen->column,
size * sizeof (next_linep->buf[0]));
current_linep->len = screen->column;
+ for (i = 0; i < screen->nterms; i++)
+ {
+ grub_free (current_linep->pos[i]);
+ current_linep->pos[i] = 0;
+ }
next_linep->len = size;
/* Update a dirty region. */
@@ -457,12 +437,6 @@ insert_string (struct screen *screen, const char *s, int update)
/* Move the cursor. */
screen->column = screen->real_column = 0;
screen->line++;
- for (i = 0; i < screen->nterms; i++)
- {
- screen->terms[i].x = 0;
- screen->terms[i].y++;
- screen->terms[i].y_line_start = screen->terms[i].y;
- }
s++;
}
else
@@ -502,6 +476,12 @@ insert_string (struct screen *screen, const char *s, int update)
grub_free (unicode_msg);
for (i = 0; i < screen->nterms; i++)
+ {
+ grub_free (current_linep->pos[i]);
+ current_linep->pos[i] = 0;
+ }
+
+ for (i = 0; i < screen->nterms; i++)
orig_num[i] = get_logical_num_lines (current_linep,
&screen->terms[i]);
current_linep->len += size;
@@ -582,7 +562,7 @@ make_screen (grub_menu_entry_t entry)
goto fail;
/* Initialize the first line which must be always present. */
- if (! init_line (screen->lines))
+ if (! init_line (screen, screen->lines))
goto fail;
insert_string (screen, (char *) entry->sourcecode, 0);
@@ -593,9 +573,7 @@ make_screen (grub_menu_entry_t entry)
screen->line = 0;
for (i = 0; i < screen->nterms; i++)
{
- screen->terms[i].x = 0;
- screen->terms[i].y = 0;
- screen->terms[i].y_line_start = screen->terms[i].y;
+ screen->terms[i].y_line_start = 0;
}
return screen;
@@ -609,21 +587,20 @@ static int
forward_char (struct screen *screen, int update)
{
struct line *linep;
- unsigned i;
linep = screen->lines + screen->line;
if (screen->column < linep->len)
- advance (screen);
+ {
+ screen->column = grub_unicode_get_comb_end (screen->lines[screen->line].buf
+ + screen->lines[screen->line].len,
+ screen->lines[screen->line].buf
+ + screen->column + 1)
+ - screen->lines[screen->line].buf;
+ }
else if (screen->num_lines > screen->line + 1)
{
screen->column = 0;
screen->line++;
- for (i = 0; i < screen->nterms; i++)
- {
- screen->terms[i].x = 0;
- screen->terms[i].y++;
- screen->terms[i].y_line_start = screen->terms[i].y;
- }
}
screen->real_column = screen->column;
@@ -636,8 +613,6 @@ forward_char (struct screen *screen, int update)
static int
backward_char (struct screen *screen, int update)
{
- unsigned i;
-
if (screen->column > 0)
{
struct grub_unicode_glyph glyph;
@@ -653,36 +628,16 @@ backward_char (struct screen *screen, int update)
grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column,
screen->lines[screen->line].len - screen->column,
&glyph);
+ screen->column = grub_unicode_get_comb_start (linep->buf,
+ linep->buf + screen->column)
+ - linep->buf;
- for (i = 0; i < screen->nterms; i++)
- {
- grub_ssize_t width;
- width = grub_term_getcharwidth (screen->terms[i].term, &glyph);
- screen->terms[i].x -= width;
- if (screen->terms[i].x < 0)
- {
- screen->terms[i].x
- = grub_term_entry_width (screen->terms[i].term) - 1;
- screen->terms[i].y--;
- }
- }
grub_free (glyph.combining);
}
else if (screen->line > 0)
{
- struct line *linep;
-
- screen->column = 0;
screen->line--;
- linep = screen->lines + screen->line;
-
- for (i = 0; i < screen->nterms; i++)
- {
- screen->terms[i].y_line_start -= get_logical_num_lines (linep, &screen->terms[i]);
- screen->terms[i].y = screen->terms[i].y_line_start;
- screen->terms[i].x = 0;
- }
- advance_to (screen, screen->lines[screen->line].len);
+ screen->column = screen->lines[screen->line].len;
}
screen->real_column = screen->column;
@@ -696,8 +651,6 @@ backward_char (struct screen *screen, int update)
static int
previous_line (struct screen *screen, int update)
{
- unsigned i;
-
if (screen->line > 0)
{
struct line *linep;
@@ -712,22 +665,10 @@ previous_line (struct screen *screen, int update)
col = screen->real_column;
screen->column = 0;
-
- for (i = 0; i < screen->nterms; i++)
- {
- screen->terms[i].y_line_start -= get_logical_num_lines (linep, &screen->terms[i]);
- screen->terms[i].y = screen->terms[i].y_line_start;
- screen->terms[i].x = 0;
- }
advance_to (screen, col);
}
else
{
- for (i = 0; i < screen->nterms; i++)
- {
- screen->terms[i].y = screen->terms[i].y_line_start;
- screen->terms[i].x = 0;
- }
screen->column = 0;
}
@@ -740,8 +681,6 @@ previous_line (struct screen *screen, int update)
static int
next_line (struct screen *screen, int update)
{
- unsigned i;
-
if (screen->line < screen->num_lines - 1)
{
struct line *linep;
@@ -758,12 +697,6 @@ next_line (struct screen *screen, int update)
c = screen->real_column;
screen->column = 0;
- for (i = 0; i < screen->nterms; i++)
- {
- screen->terms[i].y_line_start += get_logical_num_lines (linep, &screen->terms[i]);
- screen->terms[i].x = 0;
- screen->terms[i].y = screen->terms[i].y_line_start;
- }
advance_to (screen, c);
}
else
@@ -778,14 +711,7 @@ next_line (struct screen *screen, int update)
static int
beginning_of_line (struct screen *screen, int update)
{
- unsigned i;
-
screen->column = screen->real_column = 0;
- for (i = 0; i < screen->nterms; i++)
- {
- screen->terms[i].x = 0;
- screen->terms[i].y = screen->terms[i].y_line_start;
- }
if (update)
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
@@ -826,6 +752,11 @@ delete_char (struct screen *screen, int update)
* sizeof (linep->buf[0]));
linep->len--;
+ for (i = 0; i < screen->nterms; i++)
+ {
+ grub_free (linep->pos[i]);
+ linep->pos[i] = 0;
+ }
start = screen->line;
column = screen->column;
@@ -848,6 +779,7 @@ delete_char (struct screen *screen, int update)
else if (screen->num_lines > screen->line + 1)
{
struct line *next_linep;
+ unsigned i;
next_linep = linep + 1;
if (! ensure_space (linep, next_linep->len))
@@ -856,6 +788,11 @@ delete_char (struct screen *screen, int update)
grub_memmove (linep->buf + linep->len, next_linep->buf,
next_linep->len * sizeof (linep->buf[0]));
linep->len += next_linep->len;
+ for (i = 0; i < screen->nterms; i++)
+ {
+ grub_free (linep->pos[i]);
+ linep->pos[i] = 0;
+ }
grub_free (next_linep->buf);
grub_memmove (next_linep,
@@ -975,24 +912,12 @@ yank (struct screen *screen, int update)
static int
open_line (struct screen *screen, int update)
{
- int saved_y[screen->nterms];
- unsigned i;
-
- for (i = 0; i < screen->nterms; i++)
- saved_y[i] = screen->terms[i].y;
-
if (! insert_string (screen, "\n", 0))
return 0;
if (! backward_char (screen, 0))
return 0;
- for (i = 0; i < screen->nterms; i++)
- {
- screen->terms[i].y = saved_y[i];
- screen->terms[i].y_line_start = screen->terms[i].y;
- }
-
if (update)
update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);
@@ -1205,32 +1130,6 @@ run (struct screen *screen)
grub_menu_t menu = NULL;
char *dummy[1] = { NULL };
- auto char * editor_getsource (void);
- char * editor_getsource (void)
- {
- int i;
- grub_size_t size = 0, tot_size = 0;
- char *source;
-
- for (i = 0; i < screen->num_lines; i++)
- tot_size += grub_get_num_of_utf8_bytes (screen->lines[i].buf,
- screen->lines[i].len) + 1;
-
- source = grub_malloc (tot_size + 1);
- if (! source)
- return NULL;
-
- for (i = 0; i < screen->num_lines; i++)
- {
- size += grub_ucs4_to_utf8 (screen->lines[i].buf, screen->lines[i].len,
- (grub_uint8_t *) source + size,
- tot_size - size);
- source[size++] = '\n';
- }
- source[size] = '\0';
- return source;
- }
-
grub_cls ();
grub_printf (" ");
grub_printf_ (N_("Booting a command list"));
@@ -1248,9 +1147,27 @@ run (struct screen *screen)
}
/* Execute the script, line for line. */
- script = editor_getsource ();
- if (! script)
- return 0;
+ {
+ int i;
+ grub_size_t size = 0, tot_size = 0;
+
+ for (i = 0; i < screen->num_lines; i++)
+ tot_size += grub_get_num_of_utf8_bytes (screen->lines[i].buf,
+ screen->lines[i].len) + 1;
+
+ script = grub_malloc (tot_size + 1);
+ if (! script)
+ return 0;
+
+ for (i = 0; i < screen->num_lines; i++)
+ {
+ size += grub_ucs4_to_utf8 (screen->lines[i].buf, screen->lines[i].len,
+ (grub_uint8_t *) script + size,
+ tot_size - size);
+ script[size++] = '\n';
+ }
+ script[size] = '\0';
+ }
grub_script_execute_sourcecode (script, 0, dummy);
grub_free (script);
@@ -1311,7 +1228,20 @@ grub_menu_entry_run (grub_menu_entry_t entry)
screen->nterms = 0;
FOR_ACTIVE_TERM_OUTPUTS(term)
screen->nterms++;
- screen->terms = grub_malloc (screen->nterms * sizeof (screen->terms[0]));
+
+ for (i = 0; i < (unsigned) screen->num_lines; i++)
+ {
+ grub_free (screen->lines[i].pos);
+ screen->lines[i].pos = grub_zalloc (screen->nterms * sizeof (screen->lines[i].pos[0]));
+ if (! screen->lines[i].pos)
+ {
+ grub_print_error ();
+ grub_errno = GRUB_ERR_NONE;
+ return;
+ }
+ }
+
+ screen->terms = grub_zalloc (screen->nterms * sizeof (screen->terms[0]));
if (!screen->terms)
{
grub_print_error ();
@@ -1322,9 +1252,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
FOR_ACTIVE_TERM_OUTPUTS(term)
{
screen->terms[i].term = term;
- screen->terms[i].x = 0;
- screen->terms[i].y = 0;
- screen->terms[i].y_line_start = screen->terms[i].y;
+ screen->terms[i].y_line_start = 0;
i++;
}
/* Draw the screen. */
diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
index 1687c28..0031b0c 100644
--- a/grub-core/normal/menu_text.c
+++ b/grub-core/normal/menu_text.c
@@ -225,8 +225,10 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
return;
}
- grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
- grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
+ old_color_normal = grub_term_normal_color;
+ old_color_highlight = grub_term_highlight_color;
+ grub_term_normal_color = grub_color_menu_normal;
+ grub_term_highlight_color = grub_color_menu_highlight;
grub_term_setcolorstate (term, highlight
? GRUB_TERM_COLOR_HIGHLIGHT
: GRUB_TERM_COLOR_NORMAL);
@@ -293,7 +295,9 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
grub_term_gotoxy (term, grub_term_cursor_x (term), y);
- grub_term_setcolor (term, old_color_normal, old_color_highlight);
+ grub_term_normal_color = old_color_normal;
+ grub_term_highlight_color = old_color_highlight;
+
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_free (unicode_title);
}
@@ -349,11 +353,11 @@ grub_menu_init_page (int nested, int edit, int *num_entries,
*num_entries = grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y
- (print_message (nested, edit, term, 1) + 3) - 2;
- grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
-
/* By default, use the same colors for the menu. */
- grub_color_menu_normal = old_color_normal;
- grub_color_menu_highlight = old_color_highlight;
+ old_color_normal = grub_term_normal_color;
+ old_color_highlight = grub_term_highlight_color;
+ grub_color_menu_normal = grub_term_normal_color;
+ grub_color_menu_highlight = grub_term_highlight_color;
/* Then give user a chance to replace them. */
grub_parse_color_name_pair (&grub_color_menu_normal,
@@ -362,9 +366,11 @@ grub_menu_init_page (int nested, int edit, int *num_entries,
grub_env_get ("menu_color_highlight"));
grub_normal_init_page (term);
- grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
+ grub_term_normal_color = grub_color_menu_normal;
+ grub_term_highlight_color = grub_color_menu_highlight;
draw_border (term, *num_entries);
- grub_term_setcolor (term, old_color_normal, old_color_highlight);
+ grub_term_normal_color = old_color_normal;
+ grub_term_highlight_color = old_color_highlight;
print_message (nested, edit, term, 0);
}
diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c
index dc5fdcb..dc03268 100644
--- a/grub-core/normal/term.c
+++ b/grub-core/normal/term.c
@@ -34,6 +34,10 @@ struct term_state
int backlog_fixed_tab;
grub_size_t backlog_len;
+ int bidi_stack_depth;
+ grub_uint8_t bidi_stack[GRUB_BIDI_MAX_EXPLICIT_LEVEL];
+ int invalid_pushes;
+
void *free;
int num_lines;
char *term_name;
@@ -44,7 +48,9 @@ print_ucs4_real (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term, int backlog,
- int dry_run, int fixed_tab);
+ int dry_run, int fixed_tab, unsigned skip_lines,
+ unsigned max_lines,
+ grub_uint32_t contchar, struct grub_term_pos *pos);
static struct term_state *term_states = NULL;
@@ -243,7 +249,8 @@ grub_puts_terminal (const char *str, struct grub_term_output *term)
return;
}
- print_ucs4_real (unicode_str, unicode_last_position, 0, 0, term, 0, 0, 0);
+ print_ucs4_real (unicode_str, unicode_last_position, 0, 0, term,
+ 0, 0, 0, 0, -1, 0, 0);
grub_free (unicode_str);
}
@@ -541,13 +548,25 @@ get_startwidth (struct grub_term_output *term,
return ((term->getxy (term) >> 8) & 0xff) - margin_left;
}
+static void
+fill_margin (struct grub_term_output *term, int r)
+{
+ int sp = (term->getwh (term) >> 8)
+ - (term->getxy (term) >> 8) - r;
+ if (sp > 0)
+ grub_print_spaces (term, sp);
+}
+
static int
print_ucs4_terminal (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term,
struct term_state *state,
- int dry_run, int fixed_tab)
+ int dry_run, int fixed_tab, unsigned skip_lines,
+ unsigned max_lines,
+ grub_uint32_t contchar,
+ int primitive_wrap, struct grub_term_pos *pos)
{
const grub_uint32_t *ptr;
grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left);
@@ -556,10 +575,40 @@ print_ucs4_terminal (const grub_uint32_t * str,
grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right);
const grub_uint32_t *line_start = str, *last_space = str - 1;
int lines = 0;
+ int i;
+ struct term_state local_state;
+
+ if (!state)
+ {
+ grub_memset (&local_state, 0, sizeof (local_state));
+ state = &local_state;
+ }
+
+ for (i = 0; i < state->bidi_stack_depth; i++)
+ putcode_real (state->bidi_stack[i] | (GRUB_UNICODE_LRE & ~0xff),
+ term, fixed_tab);
for (ptr = str; ptr < last_position; ptr++)
{
grub_ssize_t last_width = 0;
+ switch (*ptr)
+ {
+ case GRUB_UNICODE_LRE:
+ case GRUB_UNICODE_RLE:
+ case GRUB_UNICODE_LRO:
+ case GRUB_UNICODE_RLO:
+ if (state->bidi_stack_depth >= (int) ARRAY_SIZE (state->bidi_stack))
+ state->invalid_pushes++;
+ else
+ state->bidi_stack[state->bidi_stack_depth++] = *ptr;
+ break;
+ case GRUB_UNICODE_PDF:
+ if (state->invalid_pushes)
+ state->invalid_pushes--;
+ else if (state->bidi_stack_depth)
+ state->bidi_stack_depth--;
+ break;
+ }
if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE)
{
struct grub_unicode_glyph c = {
@@ -569,10 +618,16 @@ print_ucs4_terminal (const grub_uint32_t * str,
.combining = 0
};
c.base = *ptr;
+ if (pos)
+ {
+ pos[ptr - str].x = line_width;
+ pos[ptr - str].y = lines;
+ pos[ptr - str].valid = 1;
+ }
line_width += last_width = grub_term_getcharwidth (term, &c);
}
- if (*ptr == ' ')
+ if (*ptr == ' ' && !primitive_wrap)
{
lastspacewidth = line_width;
last_space = ptr;
@@ -581,6 +636,13 @@ print_ucs4_terminal (const grub_uint32_t * str,
if (line_width > max_width || *ptr == '\n')
{
const grub_uint32_t *ptr2;
+ int wasn = (*ptr == '\n');
+
+ if (wasn)
+ {
+ state->bidi_stack_depth = 0;
+ state->invalid_pushes = 0;
+ }
if (line_width > max_width && last_space > line_start)
ptr = last_space;
@@ -595,7 +657,7 @@ print_ucs4_terminal (const grub_uint32_t * str,
lines++;
- if (!dry_run)
+ if (!skip_lines && !dry_run)
{
for (ptr2 = line_start; ptr2 < ptr; ptr2++)
{
@@ -608,9 +670,13 @@ print_ucs4_terminal (const grub_uint32_t * str,
putcode_real (*ptr2, term, fixed_tab);
}
- grub_print_spaces (term, margin_right);
+ if (!wasn && contchar)
+ putcode_real (contchar, term, fixed_tab);
+ if (contchar)
+ fill_margin (term, margin_right);
+
grub_putcode ('\n', term);
- if (state && ++state->num_lines
+ if (state != &local_state && ++state->num_lines
>= (grub_ssize_t) grub_term_height (term) - 2)
{
state->backlog_ucs4 = (ptr == last_space || *ptr == '\n')
@@ -622,17 +688,42 @@ print_ucs4_terminal (const grub_uint32_t * str,
}
line_width -= lastspacewidth;
- if (!dry_run)
- grub_print_spaces (term, margin_left);
if (ptr == last_space || *ptr == '\n')
ptr++;
line_start = ptr;
+
+ if (skip_lines)
+ skip_lines--;
+ else if (max_lines != (unsigned) -1)
+ {
+ max_lines--;
+ if (!max_lines)
+ break;
+ }
+ if (!skip_lines && !dry_run)
+ {
+ if (!contchar)
+ grub_print_spaces (term, margin_left);
+ else
+ grub_term_gotoxy (term, margin_left,
+ grub_term_getxy (term) & 0xff);
+ for (i = 0; i < state->bidi_stack_depth; i++)
+ putcode_real (state->bidi_stack[i] | (GRUB_UNICODE_LRE & ~0xff),
+ term, fixed_tab);
+ }
}
}
+ if (pos)
+ {
+ pos[ptr - str].x = line_width;
+ pos[ptr - str].y = lines;
+ pos[ptr - str].valid = 1;
+ }
+
if (line_start < last_position)
lines++;
- if (!dry_run)
+ if (!dry_run && !skip_lines && max_lines)
{
const grub_uint32_t *ptr2;
for (ptr2 = line_start; ptr2 < last_position; ptr2++)
@@ -717,7 +808,8 @@ print_backlog (struct grub_term_output *term,
ret = print_ucs4_terminal (state->backlog_ucs4,
state->backlog_ucs4 + state->backlog_len,
margin_left, margin_right, term, state, 0,
- state->backlog_fixed_tab);
+ state->backlog_fixed_tab, 0, -1, 0, 0,
+ 0);
if (!ret)
{
grub_free (state->free);
@@ -753,17 +845,28 @@ print_ucs4_real (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term, int backlog,
- int dry_run, int fixed_tab)
+ int dry_run, int fixed_tab, unsigned skip_lines,
+ unsigned max_lines,
+ grub_uint32_t contchar, struct grub_term_pos *pos)
{
struct term_state *state = NULL;
if (!dry_run)
{
+ int xy;
if (backlog)
state = find_term_state (term);
- if (((term->getxy (term) >> 8) & 0xff) < margin_left)
- grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff));
+ xy = term->getxy (term);
+
+ if (((xy >> 8) & 0xff) < margin_left)
+ {
+ if (!contchar)
+ grub_print_spaces (term, margin_left - ((xy >> 8) & 0xff));
+ else
+ grub_term_gotoxy (term, margin_left,
+ xy & 0xff);
+ }
}
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
@@ -773,7 +876,10 @@ print_ucs4_real (const grub_uint32_t * str,
{
grub_ssize_t visual_len;
struct grub_unicode_glyph *visual;
+ grub_ssize_t visual_len_show;
+ struct grub_unicode_glyph *visual_show;
int ret;
+ struct grub_unicode_glyph *vptr;
auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c);
grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c)
@@ -787,27 +893,45 @@ print_ucs4_real (const grub_uint32_t * str,
margin_left,
margin_right),
get_startwidth (term,
- margin_left));
+ margin_left),
+ contchar, pos, !!contchar);
if (visual_len < 0)
{
grub_print_error ();
return 0;
}
+ visual_show = visual;
+ for (; skip_lines && visual_show < visual + visual_len; visual_show++)
+ if (visual_show->base == '\n')
+ skip_lines--;
+ if (max_lines != (unsigned) -1)
+ {
+ for (vptr = visual_show;
+ max_lines && vptr < visual + visual_len; vptr++)
+ if (visual_show->base == '\n')
+ max_lines--;
+
+ visual_len_show = vptr - visual_show;
+ }
+ else
+ visual_len_show = visual + visual_len - visual_show;
+
if (dry_run)
{
- struct grub_unicode_glyph *vptr;
ret = 0;
- for (vptr = visual; vptr < visual + visual_len; vptr++)
+ for (vptr = visual_show; vptr < visual_show + visual_len_show; vptr++)
if (vptr->base == '\n')
ret++;
- if (visual_len && visual[visual_len - 1].base != '\n')
+ if (visual_len_show && visual[visual_len_show - 1].base != '\n')
ret++;
grub_free (visual);
}
else
{
- ret = put_glyphs_terminal (visual, visual_len, margin_left,
- margin_right, term, state, fixed_tab);
+ ret = put_glyphs_terminal (visual_show, visual_len_show, margin_left,
+ contchar ? margin_right : 1,
+ term, state, fixed_tab);
+
if (!ret)
grub_free (visual);
else
@@ -816,7 +940,22 @@ print_ucs4_real (const grub_uint32_t * str,
return ret;
}
return print_ucs4_terminal (str, last_position, margin_left, margin_right,
- term, state, dry_run, fixed_tab);
+ term, state, dry_run, fixed_tab, skip_lines,
+ max_lines, contchar, !!contchar, pos);
+}
+
+void
+grub_print_ucs4_menu (const grub_uint32_t * str,
+ const grub_uint32_t * last_position,
+ int margin_left, int margin_right,
+ struct grub_term_output *term,
+ int skip_lines, int max_lines,
+ grub_uint32_t contchar,
+ struct grub_term_pos *pos)
+{
+ print_ucs4_real (str, last_position, margin_left, margin_right,
+ term, 0, 0, 1, skip_lines, max_lines,
+ contchar, pos);
}
void
@@ -826,7 +965,7 @@ grub_print_ucs4 (const grub_uint32_t * str,
struct grub_term_output *term)
{
print_ucs4_real (str, last_position, margin_left, margin_right,
- term, 0, 0, 1);
+ term, 0, 0, 1, 0, -1, 0, 0);
}
int
@@ -836,7 +975,7 @@ grub_ucs4_count_lines (const grub_uint32_t * str,
struct grub_term_output *term)
{
return print_ucs4_real (str, last_position, margin_left, margin_right,
- term, 0, 1, 1);
+ term, 0, 1, 1, 0, -1, 0, 0);
}
void
@@ -886,7 +1025,7 @@ grub_xputs_normal (const char *str)
{
int cur;
cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0,
- term, grub_more, 0, 0);
+ term, grub_more, 0, 0, 0, -1, 0, 0);
if (cur)
backlog = 1;
}
diff --git a/grub-core/partmap/acorn.c b/grub-core/partmap/acorn.c
index 341b8ac..4d7f500 100644
--- a/grub-core/partmap/acorn.c
+++ b/grub-core/partmap/acorn.c
@@ -101,8 +101,8 @@ fail:
static grub_err_t
acorn_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition part;
struct linux_part map[LINUX_MAP_ENTRIES];
@@ -127,7 +127,7 @@ acorn_partition_map_iterate (grub_disk_t disk,
part.offset = 6;
part.number = part.index = i;
- if (hook (disk, &part))
+ if (hook (disk, &part, hook_data))
return grub_errno;
}
diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c
index 0b89cdc..213d707 100644
--- a/grub-core/partmap/amiga.c
+++ b/grub-core/partmap/amiga.c
@@ -87,8 +87,8 @@ amiga_partition_map_checksum (void *buf, grub_size_t sz)
static grub_err_t
amiga_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition part;
struct grub_amiga_rdsk rdsk;
@@ -145,7 +145,7 @@ amiga_partition_map_iterate (grub_disk_t disk,
part.index = 0;
part.partmap = &grub_amiga_partition_map;
- if (hook (disk, &part))
+ if (hook (disk, &part, hook_data))
return grub_errno;
next = grub_be_to_cpu32 (apart.next);
diff --git a/grub-core/partmap/apple.c b/grub-core/partmap/apple.c
index c08cae5..f4e608f 100644
--- a/grub-core/partmap/apple.c
+++ b/grub-core/partmap/apple.c
@@ -101,8 +101,8 @@ static struct grub_partition_map grub_apple_partition_map;
static grub_err_t
apple_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition part;
struct grub_apple_header aheader;
@@ -163,7 +163,7 @@ apple_partition_map_iterate (grub_disk_t disk,
grub_be_to_cpu32 (apart.first_phys_block),
grub_be_to_cpu32 (apart.blockcnt));
- if (hook (disk, &part))
+ if (hook (disk, &part, hook_data))
return grub_errno;
pos += grub_be_to_cpu16 (aheader.blocksize);
diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c
index c806f19..16b9c87 100644
--- a/grub-core/partmap/bsdlabel.c
+++ b/grub-core/partmap/bsdlabel.c
@@ -41,8 +41,7 @@ static struct grub_partition_map grub_openbsdlabel_partition_map;
static grub_err_t
iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
struct grub_partition_map *pmap,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook, void *hook_data)
{
struct grub_partition_bsd_disk_label label;
struct grub_partition p;
@@ -116,7 +115,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
p.start -= delta;
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
return grub_errno;
}
return GRUB_ERR_NONE;
@@ -124,14 +123,14 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
static grub_err_t
bsdlabel_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
== 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD)
return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1,
- &grub_bsdlabel_partition_map, hook);
+ &grub_bsdlabel_partition_map, hook, hook_data);
if (disk->partition
&& (grub_strcmp (disk->partition->partmap->name, "msdos") == 0
@@ -141,7 +140,44 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0,
- &grub_bsdlabel_partition_map, hook);
+ &grub_bsdlabel_partition_map, hook, hook_data);
+}
+
+/* Context for netopenbsdlabel_partition_map_iterate. */
+struct netopenbsdlabel_ctx
+{
+ grub_uint8_t type;
+ struct grub_partition_map *pmap;
+ grub_partition_iterate_hook_t hook;
+ void *hook_data;
+ int count;
+};
+
+/* Helper for netopenbsdlabel_partition_map_iterate. */
+static int
+check_msdos (grub_disk_t dsk, const grub_partition_t partition, void *data)
+{
+ struct netopenbsdlabel_ctx *ctx = data;
+ grub_err_t err;
+
+ if (partition->msdostype != ctx->type)
+ return 0;
+
+ err = iterate_real (dsk, partition->start
+ + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, ctx->pmap,
+ ctx->hook, ctx->hook_data);
+ if (err == GRUB_ERR_NONE)
+ {
+ ctx->count++;
+ return 1;
+ }
+ if (err == GRUB_ERR_BAD_PART_TABLE)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ grub_print_error ();
+ return 0;
}
/* This is a total breakage. Even when net-/openbsd label is inside partition
@@ -150,45 +186,26 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
static grub_err_t
netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
struct grub_partition_map *pmap,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
int count = 0;
- auto int check_msdos (grub_disk_t dsk,
- const grub_partition_t partition);
-
- int check_msdos (grub_disk_t dsk,
- const grub_partition_t partition)
- {
- grub_err_t err;
-
- if (partition->msdostype != type)
- return 0;
-
- err = iterate_real (dsk, partition->start
- + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, hook);
- if (err == GRUB_ERR_NONE)
- {
- count++;
- return 1;
- }
- if (err == GRUB_ERR_BAD_PART_TABLE)
- {
- grub_errno = GRUB_ERR_NONE;
- return 0;
- }
- grub_print_error ();
- return 0;
- }
-
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
== 0)
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
{
+ struct netopenbsdlabel_ctx ctx = {
+ .type = type,
+ .pmap = pmap,
+ .hook = hook,
+ .hook_data = hook_data,
+ .count = count
+ };
grub_err_t err;
- err = grub_partition_msdos_iterate (disk, check_msdos);
+
+ err = grub_partition_msdos_iterate (disk, check_msdos, &ctx);
if (err)
return err;
@@ -200,24 +217,24 @@ netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type,
static grub_err_t
netbsdlabel_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
return netopenbsdlabel_partition_map_iterate (disk,
GRUB_PC_PARTITION_TYPE_NETBSD,
&grub_netbsdlabel_partition_map,
- hook);
+ hook, hook_data);
}
static grub_err_t
openbsdlabel_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
return netopenbsdlabel_partition_map_iterate (disk,
GRUB_PC_PARTITION_TYPE_OPENBSD,
&grub_openbsdlabel_partition_map,
- hook);
+ hook, hook_data);
}
diff --git a/grub-core/partmap/dvh.c b/grub-core/partmap/dvh.c
index 79ec01b..5b464da 100644
--- a/grub-core/partmap/dvh.c
+++ b/grub-core/partmap/dvh.c
@@ -64,8 +64,7 @@ grub_dvh_is_valid (grub_uint32_t *label)
static grub_err_t
dvh_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook, void *hook_data)
{
struct grub_partition p;
union
@@ -101,7 +100,7 @@ dvh_partition_map_iterate (grub_disk_t disk,
p.start = grub_be_to_cpu32 (block.dvh.parts[partnum].start);
p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length);
p.number = p.index = partnum;
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
break;
}
diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c
index 17f242d..38df7b3 100644
--- a/grub-core/partmap/gpt.c
+++ b/grub-core/partmap/gpt.c
@@ -48,8 +48,8 @@ static struct grub_partition_map grub_gpt_partition_map;
grub_err_t
grub_gpt_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition part;
struct grub_gpt_header gpt;
@@ -113,7 +113,7 @@ grub_gpt_partition_map_iterate (grub_disk_t disk,
(unsigned long long) part.start,
(unsigned long long) part.len);
- if (hook (disk, &part))
+ if (hook (disk, &part, hook_data))
return grub_errno;
}
@@ -129,71 +129,81 @@ grub_gpt_partition_map_iterate (grub_disk_t disk,
}
#ifdef GRUB_UTIL
+/* Context for gpt_partition_map_embed. */
+struct gpt_partition_map_embed_ctx
+{
+ grub_disk_addr_t start, len;
+};
+
+/* Helper for gpt_partition_map_embed. */
+static int
+find_usable_region (grub_disk_t disk __attribute__ ((unused)),
+ const grub_partition_t p, void *data)
+{
+ struct gpt_partition_map_embed_ctx *ctx = data;
+ struct grub_gpt_partentry gptdata;
+ grub_partition_t p2;
+
+ p2 = disk->partition;
+ disk->partition = p->parent;
+ if (grub_disk_read (disk, p->offset, p->index,
+ sizeof (gptdata), &gptdata))
+ {
+ disk->partition = p2;
+ return 0;
+ }
+ disk->partition = p2;
+
+ /* If there's an embed region, it is in a dedicated partition. */
+ if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16))
+ {
+ ctx->start = p->start;
+ ctx->len = p->len;
+ return 1;
+ }
+
+ return 0;
+}
+
static grub_err_t
-gpt_partition_map_embed (struct grub_disk *disk_, unsigned int *nsectors,
+gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
unsigned int max_nsectors,
grub_embed_type_t embed_type,
grub_disk_addr_t **sectors)
{
- grub_disk_addr_t start = 0, len = 0;
+ struct gpt_partition_map_embed_ctx ctx = {
+ .start = 0,
+ .len = 0
+ };
unsigned i;
grub_err_t err;
- auto int NESTED_FUNC_ATTR find_usable_region (grub_disk_t disk,
- const grub_partition_t p);
- int NESTED_FUNC_ATTR find_usable_region (grub_disk_t disk __attribute__ ((unused)),
- const grub_partition_t p)
- {
- struct grub_gpt_partentry gptdata;
- grub_partition_t p2;
-
- p2 = disk->partition;
- disk->partition = p->parent;
- if (grub_disk_read (disk, p->offset, p->index,
- sizeof (gptdata), &gptdata))
- {
- disk->partition = p2;
- return 0;
- }
- disk->partition = p2;
-
- /* If there's an embed region, it is in a dedicated partition. */
- if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16))
- {
- start = p->start;
- len = p->len;
- return 1;
- }
-
- return 0;
- }
-
if (embed_type != GRUB_EMBED_PCBIOS)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"GPT currently supports only PC-BIOS embedding");
- err = grub_gpt_partition_map_iterate (disk_, find_usable_region);
+ err = grub_gpt_partition_map_iterate (disk, find_usable_region, &ctx);
if (err)
return err;
- if (len == 0)
+ if (ctx.len == 0)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
N_("this GPT partition label contains no BIOS Boot Partition;"
" embedding won't be possible"));
- if (len < *nsectors)
+ if (ctx.len < *nsectors)
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("your BIOS Boot Partition is too small;"
" embedding won't be possible"));
- *nsectors = len;
+ *nsectors = ctx.len;
if (*nsectors > max_nsectors)
*nsectors = max_nsectors;
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
if (!*sectors)
return grub_errno;
for (i = 0; i < *nsectors; i++)
- (*sectors)[i] = start + i;
+ (*sectors)[i] = ctx.start + i;
return GRUB_ERR_NONE;
}
diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c
index 10ca3f0..b0e11c4 100644
--- a/grub-core/partmap/msdos.c
+++ b/grub-core/partmap/msdos.c
@@ -94,14 +94,21 @@ struct embed_signature embed_signatures[] =
.signature = "ycgl",
.signature_len = 4,
.type = TYPE_RAID
+ },
+ {
+ /* https://bugs.launchpad.net/bugs/987022 */
+ .name = "Acer registration utility (?)",
+ .signature = "GREGRegDone.Tag\x00",
+ .signature_len = 16,
+ .type = TYPE_SOFTWARE
}
};
#endif
grub_err_t
grub_partition_msdos_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition p;
struct grub_msdos_partition_mbr mbr;
@@ -186,7 +193,7 @@ grub_partition_msdos_iterate (grub_disk_t disk,
{
p.number++;
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
return grub_errno;
}
else if (p.number < 4)
diff --git a/grub-core/partmap/plan.c b/grub-core/partmap/plan.c
index e6e3113..83db224 100644
--- a/grub-core/partmap/plan.c
+++ b/grub-core/partmap/plan.c
@@ -31,8 +31,8 @@ static struct grub_partition_map grub_plan_partition_map;
static grub_err_t
plan_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
struct grub_partition p;
int ptr = 0;
@@ -92,7 +92,7 @@ plan_partition_map_iterate (grub_disk_t disk,
if (c != '\n')
break;
p.len -= p.start;
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
return grub_errno;
}
if (p.number == 0)
diff --git a/grub-core/partmap/sun.c b/grub-core/partmap/sun.c
index dfe51f3..cff09ae 100644
--- a/grub-core/partmap/sun.c
+++ b/grub-core/partmap/sun.c
@@ -86,8 +86,7 @@ grub_sun_is_valid (grub_uint16_t *label)
static grub_err_t
sun_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook, void *hook_data)
{
struct grub_partition p;
union
@@ -128,7 +127,7 @@ sun_partition_map_iterate (grub_disk_t disk,
p.number = p.index = partnum;
if (p.len)
{
- if (hook (disk, &p))
+ if (hook (disk, &p, hook_data))
partnum = GRUB_PARTMAP_SUN_MAX_PARTS;
}
}
diff --git a/grub-core/partmap/sunpc.c b/grub-core/partmap/sunpc.c
index 1c1fdce..7034272 100644
--- a/grub-core/partmap/sunpc.c
+++ b/grub-core/partmap/sunpc.c
@@ -68,8 +68,8 @@ grub_sun_is_valid (grub_uint16_t *label)
static grub_err_t
sun_pc_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition))
+ grub_partition_iterate_hook_t hook,
+ void *hook_data)
{
grub_partition_t p;
union
@@ -122,7 +122,7 @@ sun_pc_partition_map_iterate (grub_disk_t disk,
p->number = partnum;
if (p->len)
{
- if (hook (disk, p))
+ if (hook (disk, p, hook_data))
partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS;
}
}
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index b5e6eb0..6619c2e 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -783,6 +783,31 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
return ret;
}
+/* Helper for grub_script_execute_sourcecode. */
+static grub_err_t
+grub_script_execute_sourcecode_getline (char **line,
+ int cont __attribute__ ((unused)),
+ void *data)
+{
+ const char **source = data;
+ const char *p;
+
+ if (! *source)
+ {
+ *line = 0;
+ return 0;
+ }
+
+ p = grub_strchr (*source, '\n');
+
+ if (p)
+ *line = grub_strndup (*source, p - *source);
+ else
+ *line = grub_strdup (*source);
+ *source = p ? p + 1 : 0;
+ return 0;
+}
+
/* Execute a source script. */
grub_err_t
grub_script_execute_sourcecode (const char *source, int argc, char **args)
@@ -792,27 +817,6 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args)
struct grub_script_scope new_scope;
struct grub_script_scope *old_scope;
- auto grub_err_t getline (char **line, int cont);
- grub_err_t getline (char **line, int cont __attribute__ ((unused)))
- {
- const char *p;
-
- if (! source)
- {
- *line = 0;
- return 0;
- }
-
- p = grub_strchr (source, '\n');
-
- if (p)
- *line = grub_strndup (source, p - source);
- else
- *line = grub_strdup (source);
- source = p ? p + 1 : 0;
- return 0;
- }
-
new_scope.argv.argc = argc;
new_scope.argv.args = args;
new_scope.flags = 0;
@@ -824,8 +828,9 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args)
{
char *line;
- getline (&line, 0);
- parsed_script = grub_script_parse (line, getline);
+ grub_script_execute_sourcecode_getline (&line, 0, &source);
+ parsed_script = grub_script_parse
+ (line, grub_script_execute_sourcecode_getline, &source);
if (! parsed_script)
{
ret = grub_errno;
diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
index 396d512..128d238 100644
--- a/grub-core/script/lexer.c
+++ b/grub-core/script/lexer.c
@@ -147,7 +147,7 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
line = 0;
if (! input)
- lexerstate->getline (&line, 1);
+ lexerstate->getline (&line, 1, lexerstate->getline_data);
else
line = grub_strdup (input);
@@ -216,7 +216,7 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
struct grub_lexer_param *
grub_script_lexer_init (struct grub_parser_param *parser, char *script,
- grub_reader_getline_t arg_getline)
+ grub_reader_getline_t arg_getline, void *getline_data)
{
struct grub_lexer_param *lexerstate;
@@ -232,7 +232,10 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script,
return 0;
}
- lexerstate->getline = arg_getline; /* rest are all zeros already */
+ lexerstate->getline = arg_getline;
+ lexerstate->getline_data = getline_data;
+ /* The other elements of lexerstate are all zeros already. */
+
if (yylex_init (&lexerstate->yyscanner))
{
grub_free (lexerstate->text);
diff --git a/grub-core/script/main.c b/grub-core/script/main.c
index aa24d16..854a25a 100644
--- a/grub-core/script/main.c
+++ b/grub-core/script/main.c
@@ -22,12 +22,13 @@
#include <grub/script_sh.h>
grub_err_t
-grub_normal_parse_line (char *line, grub_reader_getline_t getline)
+grub_normal_parse_line (char *line,
+ grub_reader_getline_t getline, void *getline_data)
{
struct grub_script *parsed_script;
/* Parse the script. */
- parsed_script = grub_script_parse (line, getline);
+ parsed_script = grub_script_parse (line, getline, getline_data);
if (parsed_script)
{
diff --git a/grub-core/script/script.c b/grub-core/script/script.c
index ad30183..ec4d433 100644
--- a/grub-core/script/script.c
+++ b/grub-core/script/script.c
@@ -340,7 +340,8 @@ grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem)
/* Parse the script passed in SCRIPT and return the parsed
datastructure that is ready to be interpreted. */
struct grub_script *
-grub_script_parse (char *script, grub_reader_getline_t getline)
+grub_script_parse (char *script,
+ grub_reader_getline_t getline, void *getline_data)
{
struct grub_script *parsed;
struct grub_script_mem *membackup;
@@ -359,7 +360,8 @@ grub_script_parse (char *script, grub_reader_getline_t getline)
}
/* Initialize the lexer. */
- lexstate = grub_script_lexer_init (parsestate, script, getline);
+ lexstate = grub_script_lexer_init (parsestate, script,
+ getline, getline_data);
if (!lexstate)
{
grub_free (parsed);
diff --git a/grub-core/term/arc/console.c b/grub-core/term/arc/console.c
index 45ff267..0ccaebe 100644
--- a/grub-core/term/arc/console.c
+++ b/grub-core/term/arc/console.c
@@ -102,8 +102,6 @@ static struct grub_term_output grub_console_term_output =
.setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_console_terminfo_output,
- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
void
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
index e57a815..2d6c6f9 100644
--- a/grub-core/term/efi/console.c
+++ b/grub-core/term/efi/console.c
@@ -192,7 +192,8 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
}
static void
-grub_console_setcolorstate (struct grub_term_output *term,
+grub_console_setcolorstate (struct grub_term_output *term
+ __attribute__ ((unused)),
grub_term_color_state state)
{
grub_efi_simple_text_output_interface_t *o;
@@ -208,10 +209,10 @@ grub_console_setcolorstate (struct grub_term_output *term,
& 0x7f);
break;
case GRUB_TERM_COLOR_NORMAL:
- efi_call_2 (o->set_attributes, o, term->normal_color & 0x7f);
+ efi_call_2 (o->set_attributes, o, grub_term_normal_color & 0x7f);
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
- efi_call_2 (o->set_attributes, o, term->highlight_color & 0x7f);
+ efi_call_2 (o->set_attributes, o, grub_term_highlight_color & 0x7f);
break;
default:
break;
@@ -265,8 +266,6 @@ static struct grub_term_output grub_console_term_output =
.cls = grub_console_cls,
.setcolorstate = grub_console_setcolorstate,
.setcursor = grub_console_setcursor,
- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
};
diff --git a/grub-core/term/emu/console.c b/grub-core/term/emu/console.c
index 55e3a6b..5bd5db1 100644
--- a/grub-core/term/emu/console.c
+++ b/grub-core/term/emu/console.c
@@ -82,11 +82,11 @@ grub_ncurses_setcolorstate (struct grub_term_output *term,
grub_console_attr = A_NORMAL;
break;
case GRUB_TERM_COLOR_NORMAL:
- grub_console_cur_color = term->normal_color;
+ grub_console_cur_color = grub_term_normal_color;
grub_console_attr = A_NORMAL;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
- grub_console_cur_color = term->highlight_color;
+ grub_console_cur_color = grub_term_highlight_color;
grub_console_attr = A_STANDOUT;
break;
default:
diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c
index 12567d1..a168e01 100644
--- a/grub-core/term/gfxterm.c
+++ b/grub-core/term/gfxterm.c
@@ -1036,7 +1036,7 @@ grub_gfxterm_cls (struct grub_term_output *term)
}
static void
-grub_virtual_screen_setcolorstate (struct grub_term_output *term,
+grub_virtual_screen_setcolorstate (struct grub_term_output *term __attribute__ ((unused)),
grub_term_color_state state)
{
switch (state)
@@ -1046,11 +1046,11 @@ grub_virtual_screen_setcolorstate (struct grub_term_output *term,
break;
case GRUB_TERM_COLOR_NORMAL:
- virtual_screen.term_color = term->normal_color;
+ virtual_screen.term_color = grub_term_normal_color;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
- virtual_screen.term_color = term->highlight_color;
+ virtual_screen.term_color = grub_term_highlight_color;
break;
default:
@@ -1246,8 +1246,6 @@ static struct grub_term_output grub_video_term =
.refresh = grub_gfxterm_refresh,
.fullscreen = grub_gfxterm_fullscreen,
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
.next = 0
};
diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c
index a681435..2aa1943 100644
--- a/grub-core/term/i386/pc/console.c
+++ b/grub-core/term/i386/pc/console.c
@@ -259,7 +259,8 @@ grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
}
static void
-grub_console_setcolorstate (struct grub_term_output *term,
+grub_console_setcolorstate (struct grub_term_output *term
+ __attribute__ ((unused)),
grub_term_color_state state)
{
switch (state) {
@@ -267,10 +268,10 @@ grub_console_setcolorstate (struct grub_term_output *term,
grub_console_cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f;
break;
case GRUB_TERM_COLOR_NORMAL:
- grub_console_cur_color = term->normal_color & 0x7f;
+ grub_console_cur_color = grub_term_normal_color & 0x7f;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
- grub_console_cur_color = term->highlight_color & 0x7f;
+ grub_console_cur_color = grub_term_highlight_color & 0x7f;
break;
default:
break;
@@ -295,8 +296,6 @@ static struct grub_term_output grub_console_term_output =
.setcolorstate = grub_console_setcolorstate,
.setcursor = grub_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_CP437,
- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
void
diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c
index 74c155c..e976aec 100644
--- a/grub-core/term/i386/pc/vga_text.c
+++ b/grub-core/term/i386/pc/vga_text.c
@@ -209,18 +209,18 @@ grub_vga_text_getwh (struct grub_term_output *term __attribute__ ((unused)))
#ifndef MODE_MDA
static void
-grub_vga_text_setcolorstate (struct grub_term_output *term,
- grub_term_color_state state)
+grub_vga_text_setcolorstate (struct grub_term_output *term __attribute__ ((unused)),
+ grub_term_color_state state)
{
switch (state) {
case GRUB_TERM_COLOR_STANDARD:
cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f;
break;
case GRUB_TERM_COLOR_NORMAL:
- cur_color = term->normal_color & 0x7f;
+ cur_color = grub_term_normal_color & 0x7f;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
- cur_color = term->highlight_color & 0x7f;
+ cur_color = grub_term_highlight_color & 0x7f;
break;
default:
break;
@@ -265,8 +265,6 @@ static struct grub_term_output grub_vga_text_term =
.setcolorstate = grub_vga_text_setcolorstate,
.setcursor = grub_vga_text_setcursor,
.flags = GRUB_TERM_CODE_TYPE_CP437,
- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
#ifdef MODE_MDA
diff --git a/grub-core/term/ieee1275/console.c b/grub-core/term/ieee1275/console.c
index 93b81f4..3a80864 100644
--- a/grub-core/term/ieee1275/console.c
+++ b/grub-core/term/ieee1275/console.c
@@ -229,8 +229,6 @@ static struct grub_term_output grub_console_term_output =
.setcursor = grub_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_console_terminfo_output,
- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
void
diff --git a/grub-core/term/morse.c b/grub-core/term/morse.c
new file mode 100644
index 0000000..0fdc3b4
--- /dev/null
+++ b/grub-core/term/morse.c
@@ -0,0 +1,129 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2011,2012,2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/time.h>
+#include <grub/speaker.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+#define BASE_TIME 250
+
+static const char codes[0x80][6] =
+ {
+ ['0'] = { 3, 3, 3, 3, 3, 0 },
+ ['1'] = { 1, 3, 3, 3, 3, 0 },
+ ['2'] = { 1, 1, 3, 3, 3, 0 },
+ ['3'] = { 1, 1, 1, 3, 3, 0 },
+ ['4'] = { 1, 1, 1, 1, 3, 0 },
+ ['5'] = { 1, 1, 1, 1, 1, 0 },
+ ['6'] = { 3, 1, 1, 1, 1, 0 },
+ ['7'] = { 3, 3, 1, 1, 1, 0 },
+ ['8'] = { 3, 3, 3, 1, 1, 0 },
+ ['9'] = { 3, 3, 3, 3, 1, 0 },
+ ['a'] = { 1, 3, 0 },
+ ['b'] = { 3, 1, 1, 1, 0 },
+ ['c'] = { 3, 1, 3, 1, 0 },
+ ['d'] = { 3, 1, 1, 0 },
+ ['e'] = { 1, 0 },
+ ['f'] = { 1, 1, 3, 1, 0 },
+ ['g'] = { 3, 3, 1, 0 },
+ ['h'] = { 1, 1, 1, 1, 0 },
+ ['i'] = { 1, 1, 0 },
+ ['j'] = { 1, 3, 3, 3, 0 },
+ ['k'] = { 3, 1, 3, 0 },
+ ['l'] = { 1, 3, 1, 1, 0 },
+ ['m'] = { 3, 3, 0 },
+ ['n'] = { 3, 1, 0 },
+ ['o'] = { 3, 3, 3, 0 },
+ ['p'] = { 1, 3, 3, 1, 0 },
+ ['q'] = { 3, 3, 1, 3, 0 },
+ ['r'] = { 1, 3, 1, 0 },
+ ['s'] = { 1, 1, 1, 0 },
+ ['t'] = { 3, 0 },
+ ['u'] = { 1, 1, 3, 0 },
+ ['v'] = { 1, 1, 1, 3, 0 },
+ ['w'] = { 1, 3, 3, 0 },
+ ['x'] = { 3, 1, 1, 3, 0 },
+ ['y'] = { 3, 1, 3, 3, 0 },
+ ['z'] = { 3, 3, 1, 1, 0 }
+ };
+
+static void
+grub_audio_tone (int length)
+{
+ grub_speaker_beep_on (1000);
+ grub_millisleep (length);
+ grub_speaker_beep_off ();
+}
+
+static void
+grub_audio_putchar (struct grub_term_output *term __attribute__ ((unused)),
+ const struct grub_unicode_glyph *c_in)
+{
+ grub_uint8_t c;
+ int i;
+
+ /* For now, do not try to use a surrogate pair. */
+ if (c_in->base > 0x7f)
+ c = '?';
+ else
+ c = grub_tolower (c_in->base);
+ for (i = 0; codes[c][i]; i++)
+ {
+ grub_audio_tone (codes[c][i] * BASE_TIME);
+ grub_millisleep (BASE_TIME);
+ }
+ grub_millisleep (2 * BASE_TIME);
+}
+
+
+static int
+dummy (void)
+{
+ return 0;
+}
+
+static struct grub_term_output grub_audio_term_output =
+ {
+ .name = "morse",
+ .init = (void *) dummy,
+ .fini = (void *) dummy,
+ .putchar = grub_audio_putchar,
+ .getwh = (void *) dummy,
+ .getxy = (void *) dummy,
+ .gotoxy = (void *) dummy,
+ .cls = (void *) dummy,
+ .setcolorstate = (void *) dummy,
+ .setcursor = (void *) dummy,
+ .flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB
+ };
+
+GRUB_MOD_INIT (morse)
+{
+ grub_term_register_output ("audio", &grub_audio_term_output);
+}
+
+GRUB_MOD_FINI (morse)
+{
+ grub_term_unregister_output (&grub_audio_term_output);
+}
diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c
index e1469e5..cfcfe84 100644
--- a/grub-core/term/serial.c
+++ b/grub-core/term/serial.c
@@ -121,8 +121,6 @@ static struct grub_term_output grub_serial_term_output =
.setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_serial_terminfo_output,
- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
diff --git a/grub-core/term/spkmodem.c b/grub-core/term/spkmodem.c
new file mode 100644
index 0000000..f20a27d
--- /dev/null
+++ b/grub-core/term/spkmodem.c
@@ -0,0 +1,141 @@
+/* console.c -- Open Firmware console for GRUB. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/terminfo.h>
+#include <grub/dl.h>
+#include <grub/speaker.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+extern struct grub_terminfo_output_state grub_spkmodem_terminfo_output;
+
+static void
+make_tone (grub_uint16_t freq_count, unsigned int duration)
+{
+ /* Program timer 2. */
+ grub_outb (GRUB_PIT_CTRL_SELECT_2
+ | GRUB_PIT_CTRL_READLOAD_WORD
+ | GRUB_PIT_CTRL_SQUAREWAVE_GEN
+ | GRUB_PIT_CTRL_COUNT_BINARY, GRUB_PIT_CTRL);
+ grub_outb (freq_count & 0xff, GRUB_PIT_COUNTER_2); /* LSB */
+ grub_outb ((freq_count >> 8) & 0xff, GRUB_PIT_COUNTER_2); /* MSB */
+
+ /* Start speaker. */
+ grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
+ | GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA,
+ GRUB_PIT_SPEAKER_PORT);
+
+ for (; duration; duration--)
+ {
+ unsigned short counter, previous_counter = 0xffff;
+ while (1)
+ {
+ counter = grub_inb (GRUB_PIT_COUNTER_2);
+ counter |= ((grub_uint16_t) grub_inb (GRUB_PIT_COUNTER_2)) << 8;
+ if (counter > previous_counter)
+ {
+ previous_counter = counter;
+ break;
+ }
+ previous_counter = counter;
+ }
+ }
+}
+
+static int inited;
+
+static void
+put (struct grub_term_output *term __attribute__ ((unused)), const int c)
+{
+ int i;
+
+ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 4);
+ for (i = 7; i >= 0; i--)
+ {
+ if ((c >> i) & 1)
+ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 2000, 20);
+ else
+ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 4000, 40);
+ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 1000, 10);
+ }
+ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 0);
+}
+
+static grub_err_t
+grub_spkmodem_init_output (struct grub_term_output *term)
+{
+ /* Some models shutdown sound when not in use and it takes for it
+ around 30 ms to come back on which loses 3 bits. So generate a base
+ 200 Hz continously. */
+
+ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 0);
+ grub_terminfo_output_init (term);
+
+ return 0;
+}
+
+static grub_err_t
+grub_spkmodem_fini_output (struct grub_term_output *term __attribute__ ((unused)))
+{
+ grub_speaker_beep_off ();
+ inited = 0;
+ return 0;
+}
+
+
+
+
+struct grub_terminfo_output_state grub_spkmodem_terminfo_output =
+ {
+ .put = put,
+ .width = 80,
+ .height = 24
+ };
+
+static struct grub_term_output grub_spkmodem_term_output =
+ {
+ .name = "spkmodem",
+ .init = grub_spkmodem_init_output,
+ .fini = grub_spkmodem_fini_output,
+ .putchar = grub_terminfo_putchar,
+ .getxy = grub_terminfo_getxy,
+ .getwh = grub_terminfo_getwh,
+ .gotoxy = grub_terminfo_gotoxy,
+ .cls = grub_terminfo_cls,
+ .setcolorstate = grub_terminfo_setcolorstate,
+ .setcursor = grub_terminfo_setcursor,
+ .flags = GRUB_TERM_CODE_TYPE_ASCII,
+ .data = &grub_spkmodem_terminfo_output,
+ };
+
+GRUB_MOD_INIT (spkmodem)
+{
+ grub_term_register_output ("spkmodem", &grub_spkmodem_term_output);
+}
+
+
+GRUB_MOD_FINI (spkmodem)
+{
+ grub_term_unregister_output (&grub_spkmodem_term_output);
+}
diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c
index 9639596..fcb4cbe 100644
--- a/grub-core/term/terminfo.c
+++ b/grub-core/term/terminfo.c
@@ -303,12 +303,12 @@ grub_terminfo_setcolorstate (struct grub_term_output *term,
{
case GRUB_TERM_COLOR_STANDARD:
case GRUB_TERM_COLOR_NORMAL:
- fg = term->normal_color & 0x0f;
- bg = term->normal_color >> 4;
+ fg = grub_term_normal_color & 0x0f;
+ bg = grub_term_normal_color >> 4;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
- fg = term->highlight_color & 0x0f;
- bg = term->highlight_color >> 4;
+ fg = grub_term_highlight_color & 0x0f;
+ bg = grub_term_highlight_color >> 4;
break;
default:
return;
diff --git a/grub-core/term/uboot/console.c b/grub-core/term/uboot/console.c
index 9d56ad7..282dbbe 100644
--- a/grub-core/term/uboot/console.c
+++ b/grub-core/term/uboot/console.c
@@ -105,8 +105,6 @@ static struct grub_term_output uboot_console_term_output = {
.setcursor = uboot_console_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &uboot_console_terminfo_output,
- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
void
diff --git a/grub-core/tests/lib/test.c b/grub-core/tests/lib/test.c
index aac77e9..1d2cb8c 100644
--- a/grub-core/tests/lib/test.c
+++ b/grub-core/tests/lib/test.c
@@ -225,10 +225,14 @@ grub_test_run (grub_test_t test)
failure->line, (failure->message ? : "<no message>"));
if (!failure_list)
- grub_printf ("%s: PASS\n", test->name);
+ {
+ grub_printf ("%s: PASS\n", test->name);
+ return GRUB_ERR_NONE;
+ }
else
- grub_printf ("%s: FAIL\n", test->name);
-
- free_failures ();
- return GRUB_ERR_NONE;
+ {
+ grub_printf ("%s: FAIL\n", test->name);
+ free_failures ();
+ return GRUB_ERR_TEST_FAILURE;
+ }
}
diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c
index 79cae65..aea486c 100644
--- a/grub-core/video/bochs.c
+++ b/grub-core/video/bochs.c
@@ -199,6 +199,29 @@ grub_video_bochs_set_palette (unsigned int start, unsigned int count,
return grub_video_fb_set_palette (start, count, palette_data);
}
+/* Helper for grub_video_bochs_setup. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
+{
+ int *found = data;
+ grub_pci_address_t addr;
+ grub_uint32_t class;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ class = grub_pci_read (addr);
+
+ if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x11111234)
+ return 0;
+
+ *found = 1;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+ framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
+ framebuffer.dev = dev;
+
+ return 1;
+}
+
static grub_err_t
grub_video_bochs_setup (unsigned int width, unsigned int height,
grub_video_mode_type_t mode_type,
@@ -210,27 +233,6 @@ grub_video_bochs_setup (unsigned int width, unsigned int height,
int pitch, bytes_per_pixel;
grub_size_t page_size; /* The size of a page in bytes. */
- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid)
- {
- grub_pci_address_t addr;
- grub_uint32_t class;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
- class = grub_pci_read (addr);
-
- if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x11111234)
- return 0;
-
- found = 1;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
- framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
- framebuffer.dev = dev;
-
- return 1;
- }
-
/* Decode depth from mode_type. If it is zero, then autodetect. */
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
@@ -280,7 +282,7 @@ grub_video_bochs_setup (unsigned int width, unsigned int height,
if (page_size > BOCHS_APERTURE_SIZE)
return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode");
- grub_pci_iterate (find_card);
+ grub_pci_iterate (find_card, &found);
if (!found)
return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c
index 7fad50e..073c54e 100644
--- a/grub-core/video/cirrus.c
+++ b/grub-core/video/cirrus.c
@@ -235,6 +235,29 @@ grub_video_cirrus_set_palette (unsigned int start, unsigned int count,
return grub_video_fb_set_palette (start, count, palette_data);
}
+/* Helper for grub_video_cirrus_setup. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
+{
+ int *found = data;
+ grub_pci_address_t addr;
+ grub_uint32_t class;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ class = grub_pci_read (addr);
+
+ if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x00b81013)
+ return 0;
+
+ *found = 1;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+ framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
+ framebuffer.dev = dev;
+
+ return 1;
+}
+
static grub_err_t
grub_video_cirrus_setup (unsigned int width, unsigned int height,
grub_video_mode_type_t mode_type,
@@ -245,27 +268,6 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
int found = 0;
int pitch, bytes_per_pixel;
- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid)
- {
- grub_pci_address_t addr;
- grub_uint32_t class;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
- class = grub_pci_read (addr);
-
- if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x00b81013)
- return 0;
-
- found = 1;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
- framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
- framebuffer.dev = dev;
-
- return 1;
- }
-
/* Decode depth from mode_type. If it is zero, then autodetect. */
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
@@ -314,7 +316,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
if (framebuffer.page_size > CIRRUS_APERTURE_SIZE)
return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode");
- grub_pci_iterate (find_card);
+ grub_pci_iterate (find_card, &found);
if (!found)
return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c
index 016adbb..695f015 100644
--- a/grub-core/video/efi_uga.c
+++ b/grub-core/video/efi_uga.c
@@ -81,77 +81,88 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
return 0;
}
-static int
-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+/* Context for find_framebuf. */
+struct find_framebuf_ctx
{
- int found = 0;
+ grub_uint32_t *fb_base;
+ grub_uint32_t *line_len;
+ int found;
+};
- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
- grub_pci_id_t pciid);
+/* Helper for find_framebuf. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
+{
+ struct find_framebuf_ctx *ctx = data;
+ grub_pci_address_t addr;
- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
- grub_pci_id_t pciid)
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ if (grub_pci_read (addr) >> 24 == 0x3)
{
- grub_pci_address_t addr;
+ int i;
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
- if (grub_pci_read (addr) >> 24 == 0x3)
+ grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n",
+ grub_pci_get_bus (dev), grub_pci_get_device (dev),
+ grub_pci_get_function (dev), pciid);
+ addr += 8;
+ for (i = 0; i < 6; i++, addr += 4)
{
- int i;
-
- grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n",
- grub_pci_get_bus (dev), grub_pci_get_device (dev),
- grub_pci_get_function (dev), pciid);
- addr += 8;
- for (i = 0; i < 6; i++, addr += 4)
- {
- grub_uint32_t old_bar1, old_bar2, type;
- grub_uint64_t base64;
+ grub_uint32_t old_bar1, old_bar2, type;
+ grub_uint64_t base64;
- old_bar1 = grub_pci_read (addr);
- if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
- continue;
+ old_bar1 = grub_pci_read (addr);
+ if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
+ continue;
- type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
- if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
- {
- if (i == 5)
- break;
+ type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
+ if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+ {
+ if (i == 5)
+ break;
- old_bar2 = grub_pci_read (addr + 4);
- }
- else
- old_bar2 = 0;
+ old_bar2 = grub_pci_read (addr + 4);
+ }
+ else
+ old_bar2 = 0;
- base64 = old_bar2;
- base64 <<= 32;
- base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
+ base64 = old_bar2;
+ base64 <<= 32;
+ base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
- grub_dprintf ("fb", "%s(%d): 0x%llx\n",
- ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
- "VMEM" : "MMIO"), i,
- (unsigned long long) base64);
+ grub_dprintf ("fb", "%s(%d): 0x%llx\n",
+ ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
+ "VMEM" : "MMIO"), i,
+ (unsigned long long) base64);
- if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
- {
- *fb_base = base64;
- if (find_line_len (fb_base, line_len))
- found++;
- }
+ if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! ctx->found))
+ {
+ *ctx->fb_base = base64;
+ if (find_line_len (ctx->fb_base, ctx->line_len))
+ ctx->found++;
+ }
- if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
- {
- i++;
- addr += 4;
- }
+ if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+ {
+ i++;
+ addr += 4;
}
}
-
- return found;
}
- grub_pci_iterate (find_card);
- return found;
+ return ctx->found;
+}
+
+static int
+find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+ struct find_framebuf_ctx ctx = {
+ .fb_base = fb_base,
+ .line_len = line_len,
+ .found = 0
+ };
+
+ grub_pci_iterate (find_card, &ctx);
+ return ctx.found;
}
static int
diff --git a/grub-core/video/radeon_fuloong2e.c b/grub-core/video/radeon_fuloong2e.c
index 32f66c7..c3d65f1 100644
--- a/grub-core/video/radeon_fuloong2e.c
+++ b/grub-core/video/radeon_fuloong2e.c
@@ -60,6 +60,32 @@ grub_video_radeon_fuloong2e_video_fini (void)
return grub_video_fb_fini ();
}
+#ifndef TEST
+/* Helper for grub_video_radeon_fuloong2e_setup. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
+{
+ int *found = data;
+ grub_pci_address_t addr;
+ grub_uint32_t class;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ class = grub_pci_read (addr);
+
+ if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA
+ || pciid != 0x515a1002)
+ return 0;
+
+ *found = 1;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+ framebuffer.base = grub_pci_read (addr);
+ framebuffer.dev = dev;
+
+ return 1;
+}
+#endif
+
static grub_err_t
grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height,
unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
@@ -69,28 +95,6 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height,
int found = 0;
#ifndef TEST
- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
- {
- grub_pci_address_t addr;
- grub_uint32_t class;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
- class = grub_pci_read (addr);
-
- if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA
- || pciid != 0x515a1002)
- return 0;
-
- found = 1;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
- framebuffer.base = grub_pci_read (addr);
- framebuffer.dev = dev;
-
- return 1;
- }
-
/* Decode depth from mode_type. If it is zero, then autodetect. */
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
@@ -100,7 +104,7 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height,
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Only 640x480x16 is supported");
- grub_pci_iterate (find_card);
+ grub_pci_iterate (find_card, &found);
if (!found)
return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
#endif
diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c
index 5d06daa..a986669 100644
--- a/grub-core/video/sis315pro.c
+++ b/grub-core/video/sis315pro.c
@@ -88,6 +88,37 @@ grub_video_sis315pro_video_fini (void)
#include "sis315_init.c"
+#ifndef TEST
+/* Helper for grub_video_sis315pro_setup. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
+{
+ int *found = data;
+ grub_pci_address_t addr;
+ grub_uint32_t class;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ class = grub_pci_read (addr);
+
+ if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA
+ || pciid != GRUB_SIS315PRO_PCIID)
+ return 0;
+
+ *found = 1;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+ framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
+ framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2);
+ framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK)
+ + GRUB_MACHINE_PCI_IO_BASE;
+ framebuffer.dev = dev;
+
+ return 1;
+}
+#endif
+
static grub_err_t
grub_video_sis315pro_setup (unsigned int width, unsigned int height,
unsigned int mode_type,
@@ -99,33 +130,6 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
unsigned i;
#ifndef TEST
- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
- {
- grub_pci_address_t addr;
- grub_uint32_t class;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
- class = grub_pci_read (addr);
-
- if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA
- || pciid != GRUB_SIS315PRO_PCIID)
- return 0;
-
- found = 1;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
- framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
- framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2);
- framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK)
- + GRUB_MACHINE_PCI_IO_BASE;
- framebuffer.dev = dev;
-
- return 1;
- }
-
/* Decode depth from mode_type. If it is zero, then autodetect. */
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
@@ -135,7 +139,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Only 640x480x8 is supported");
- grub_pci_iterate (find_card);
+ grub_pci_iterate (find_card, &found);
if (!found)
return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
#endif
diff --git a/grub-core/video/sm712.c b/grub-core/video/sm712.c
index 5f22c40..fb40d64 100644
--- a/grub-core/video/sm712.c
+++ b/grub-core/video/sm712.c
@@ -360,6 +360,32 @@ grub_sm712_write_dda_lookup (int idx, grub_uint8_t compare, grub_uint16_t dda,
GRUB_SM712_CR_DDA_LOOKUP_REG1_START + idx);
}
+#if !defined (TEST) && !defined(GENINIT)
+/* Helper for grub_video_sm712_setup. */
+static int
+find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
+{
+ int *found = data;
+ grub_pci_address_t addr;
+ grub_uint32_t class;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+ class = grub_pci_read (addr);
+
+ if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA
+ || pciid != GRUB_SM712_PCIID)
+ return 0;
+
+ *found = 1;
+
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+ framebuffer.base = grub_pci_read (addr);
+ framebuffer.dev = dev;
+
+ return 1;
+}
+#endif
+
static grub_err_t
grub_video_sm712_setup (unsigned int width, unsigned int height,
unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
@@ -370,28 +396,6 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
grub_err_t err;
int found = 0;
- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
- {
- grub_pci_address_t addr;
- grub_uint32_t class;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
- class = grub_pci_read (addr);
-
- if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA
- || pciid != GRUB_SM712_PCIID)
- return 0;
-
- found = 1;
-
- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
- framebuffer.base = grub_pci_read (addr);
- framebuffer.dev = dev;
-
- return 1;
- }
-
/* Decode depth from mode_type. If it is zero, then autodetect. */
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
@@ -401,7 +405,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Only 1024x600x16 is supported");
- grub_pci_iterate (find_card);
+ grub_pci_iterate (find_card, &found);
if (!found)
return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
/* Fill mode info details. */
diff --git a/include/grub/arc/arc.h b/include/grub/arc/arc.h
index a825a98..739926f 100644
--- a/include/grub/arc/arc.h
+++ b/include/grub/arc/arc.h
@@ -255,7 +255,12 @@ struct grub_arc_system_parameter_block
#define GRUB_ARC_STDIN 0
#define GRUB_ARC_STDOUT 1
-int EXPORT_FUNC (grub_arc_iterate_devs) (int (*hook) (const char *name, const struct grub_arc_component *comp), int alt_names);
+typedef int (*grub_arc_iterate_devs_hook_t)
+ (const char *name, const struct grub_arc_component *comp, void *data);
+
+int EXPORT_FUNC (grub_arc_iterate_devs) (grub_arc_iterate_devs_hook_t hook,
+ void *hook_data,
+ int alt_names);
#define FOR_ARC_CHILDREN(comp, parent) for (comp = GRUB_ARC_FIRMWARE_VECTOR->getchild (parent); comp; comp = GRUB_ARC_FIRMWARE_VECTOR->getpeer (comp))
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
index 043994b..de4b4fe 100644
--- a/include/grub/arm/linux.h
+++ b/include/grub/arm/linux.h
@@ -24,12 +24,12 @@
#define LINUX_ZIMAGE_MAGIC 0x016f2818
#if defined GRUB_MACHINE_UBOOT
-# include <grub/uboot/uboot.h>
-# define LINUX_ADDRESS (start_of_ram + 0x8000)
-# define LINUX_INITRD_ADDRESS (start_of_ram + 0x02000000)
-# define LINUX_FDT_ADDRESS (LINUX_INITRD_ADDRESS - 0x10000)
-# define firmware_get_boot_data uboot_get_boot_data
-# define firmware_get_machine_type uboot_get_machine_type
+#include <grub/uboot/uboot.h>
+#define LINUX_ADDRESS (start_of_ram + 0x8000)
+#define LINUX_INITRD_ADDRESS (start_of_ram + 0x02000000)
+#define LINUX_FDT_ADDRESS (LINUX_INITRD_ADDRESS - 0x10000)
+#define firmware_get_boot_data uboot_get_boot_data
+#define firmware_get_machine_type uboot_get_machine_type
#endif
#define FDT_ADDITIONAL_ENTRIES_SIZE 0x300
diff --git a/include/grub/ata.h b/include/grub/ata.h
index efba7b7..e8a84b8 100644
--- a/include/grub/ata.h
+++ b/include/grub/ata.h
@@ -193,10 +193,12 @@ struct grub_ata
typedef struct grub_ata *grub_ata_t;
+typedef int (*grub_ata_dev_iterate_hook_t) (int id, int bus, void *data);
+
struct grub_ata_dev
{
/* Call HOOK with each device name, until HOOK returns non-zero. */
- int (*iterate) (int (*hook) (int id, int bus),
+ int (*iterate) (grub_ata_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull);
/* Open the device named NAME, and set up SCSI. */
diff --git a/include/grub/crypto.h b/include/grub/crypto.h
index 67e0a1b..ea2f13e 100644
--- a/include/grub/crypto.h
+++ b/include/grub/crypto.h
@@ -64,11 +64,14 @@ typedef enum
GPG_ERR_WEAK_KEY,
GPG_ERR_WRONG_KEY_USAGE,
GPG_ERR_WRONG_PUBKEY_ALGO,
- GPG_ERR_OUT_OF_MEMORY
- } gcry_err_code_t;
-#define gpg_err_code_t gcry_err_code_t
-#define gpg_error_t gcry_err_code_t
-
+ GPG_ERR_OUT_OF_MEMORY,
+ GPG_ERR_TOO_LARGE
+ } gpg_err_code_t;
+typedef gpg_err_code_t gpg_error_t;
+typedef gpg_error_t gcry_error_t;
+typedef gpg_err_code_t gcry_err_code_t;
+#define gcry_error_t gcry_err_code_t
+#if 0
enum gcry_cipher_modes
{
GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */
@@ -79,6 +82,7 @@ enum gcry_cipher_modes
GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */
GCRY_CIPHER_MODE_CTR = 6 /* Counter. */
};
+#endif
/* Type for the cipher_setkey function. */
typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
@@ -171,6 +175,74 @@ typedef struct gcry_md_spec
struct gcry_md_spec *next;
} gcry_md_spec_t;
+struct gcry_mpi;
+typedef struct gcry_mpi *gcry_mpi_t;
+
+/* Type for the pk_generate function. */
+typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
+ unsigned int nbits,
+ unsigned long use_e,
+ gcry_mpi_t *skey,
+ gcry_mpi_t **retfactors);
+
+/* Type for the pk_check_secret_key function. */
+typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
+ gcry_mpi_t *skey);
+
+/* Type for the pk_encrypt function. */
+typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo,
+ gcry_mpi_t *resarr,
+ gcry_mpi_t data,
+ gcry_mpi_t *pkey,
+ int flags);
+
+/* Type for the pk_decrypt function. */
+typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo,
+ gcry_mpi_t *result,
+ gcry_mpi_t *data,
+ gcry_mpi_t *skey,
+ int flags);
+
+/* Type for the pk_sign function. */
+typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo,
+ gcry_mpi_t *resarr,
+ gcry_mpi_t data,
+ gcry_mpi_t *skey);
+
+/* Type for the pk_verify function. */
+typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo,
+ gcry_mpi_t hash,
+ gcry_mpi_t *data,
+ gcry_mpi_t *pkey,
+ int (*cmp) (void *, gcry_mpi_t),
+ void *opaquev);
+
+/* Type for the pk_get_nbits function. */
+typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);
+
+/* Module specification structure for message digests. */
+typedef struct gcry_pk_spec
+{
+ const char *name;
+ const char **aliases;
+ const char *elements_pkey;
+ const char *elements_skey;
+ const char *elements_enc;
+ const char *elements_sig;
+ const char *elements_grip;
+ int use;
+ gcry_pk_generate_t generate;
+ gcry_pk_check_secret_key_t check_secret_key;
+ gcry_pk_encrypt_t encrypt;
+ gcry_pk_decrypt_t decrypt;
+ gcry_pk_sign_t sign;
+ gcry_pk_verify_t verify;
+ gcry_pk_get_nbits_t get_nbits;
+#ifdef GRUB_UTIL
+ const char *modname;
+#endif
+} gcry_pk_spec_t;
+
struct grub_crypto_cipher_handle
{
const struct gcry_cipher_spec *cipher;
@@ -256,6 +328,11 @@ void
grub_md_register (gcry_md_spec_t *digest);
void
grub_md_unregister (gcry_md_spec_t *cipher);
+
+extern struct gcry_pk_spec *grub_crypto_pk_dsa;
+extern struct gcry_pk_spec *grub_crypto_pk_ecdsa;
+extern struct gcry_pk_spec *grub_crypto_pk_rsa;
+
void
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
grub_size_t inlen);
@@ -319,10 +396,20 @@ grub_password_get (char buf[], unsigned buf_size);
extern void (*grub_crypto_autoload_hook) (const char *name);
+void _gcry_assert_failed (const char *expr, const char *file, int line,
+ const char *func) __attribute__ ((noreturn));
+
+void _gcry_burn_stack (int bytes);
+void _gcry_log_error( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
+void _gcry_log_bug( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
+void _gcry_log_printf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
+void
+_gcry_check_heap (const void *a __attribute__ ((unused)));
+
+
#ifdef GRUB_UTIL
void grub_gcry_init_all (void);
void grub_gcry_fini_all (void);
#endif
-
#endif
diff --git a/include/grub/device.h b/include/grub/device.h
index f3e43bf..1d1a239 100644
--- a/include/grub/device.h
+++ b/include/grub/device.h
@@ -33,8 +33,11 @@ struct grub_device
};
typedef struct grub_device *grub_device_t;
+typedef int (*grub_device_iterate_hook_t) (const char *name, void *data);
+
grub_device_t EXPORT_FUNC(grub_device_open) (const char *name);
grub_err_t EXPORT_FUNC(grub_device_close) (grub_device_t device);
-int EXPORT_FUNC(grub_device_iterate) (int (*hook) (const char *name));
+int EXPORT_FUNC(grub_device_iterate) (grub_device_iterate_hook_t hook,
+ void *hook_data);
#endif /* ! GRUB_DEVICE_HEADER */
diff --git a/include/grub/disk.h b/include/grub/disk.h
index 6979a9c..89b4d08 100644
--- a/include/grub/disk.h
+++ b/include/grub/disk.h
@@ -57,6 +57,8 @@ typedef enum
GRUB_DISK_PULL_MAX
} grub_disk_pull_t;
+typedef int (*grub_disk_dev_iterate_hook_t) (const char *name, void *data);
+
/* Disk device. */
struct grub_disk_dev
{
@@ -67,7 +69,7 @@ struct grub_disk_dev
enum grub_disk_dev_id id;
/* Call HOOK with each device name, until HOOK returns non-zero. */
- int (*iterate) (int (*hook) (const char *name),
+ int (*iterate) (grub_disk_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull);
/* Open the device named NAME, and set up DISK. */
@@ -159,14 +161,14 @@ void grub_disk_cache_invalidate_all (void);
void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev);
void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev);
static inline int
-grub_disk_dev_iterate (int (*hook) (const char *name))
+grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data)
{
grub_disk_dev_t p;
grub_disk_pull_t pull;
for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
for (p = grub_disk_dev_list; p; p = p->next)
- if (p->iterate && (p->iterate) (hook, pull))
+ if (p->iterate && (p->iterate) (hook, hook_data, pull))
return 1;
return 0;
diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h
index 4ce3fc9..f241e75 100644
--- a/include/grub/efiemu/efiemu.h
+++ b/include/grub/efiemu/efiemu.h
@@ -226,7 +226,7 @@ grub_efiemu_finish_boot_services (grub_efi_uintn_t *memory_map_size,
grub_efi_uint32_t *descriptor_version);
grub_err_t
-grub_efiemu_mmap_iterate (grub_memory_hook_t hook);
+grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data);
int grub_efiemu_sizeof_uintn_t (void);
grub_err_t
grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper);
diff --git a/include/grub/elfload.h b/include/grub/elfload.h
index aae95f5..d1a8d54 100644
--- a/include/grub/elfload.h
+++ b/include/grub/elfload.h
@@ -41,6 +41,11 @@ typedef grub_err_t (*grub_elf32_load_hook_t)
typedef grub_err_t (*grub_elf64_load_hook_t)
(Elf64_Phdr *phdr, grub_addr_t *addr, int *load);
+typedef int (*grub_elf32_phdr_iterate_hook_t)
+ (grub_elf_t elf, Elf32_Phdr *phdr, void *arg);
+typedef int (*grub_elf64_phdr_iterate_hook_t)
+ (grub_elf_t elf, Elf64_Phdr *phdr, void *arg);
+
grub_elf_t grub_elf_open (const char *);
grub_elf_t grub_elf_file (grub_file_t file, const char *filename);
grub_err_t grub_elf_close (grub_elf_t);
@@ -63,12 +68,10 @@ grub_err_t grub_elf64_load (grub_elf_t, const char *filename,
grub_err_t
grub_elf32_phdr_iterate (grub_elf_t elf,
const char *filename,
- int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *),
- void *hook_arg);
+ grub_elf32_phdr_iterate_hook_t hook, void *hook_arg);
grub_err_t
grub_elf64_phdr_iterate (grub_elf_t elf,
const char *filename,
- int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *),
- void *hook_arg);
+ grub_elf64_phdr_iterate_hook_t hook, void *hook_arg);
#endif /* ! GRUB_ELFLOAD_HEADER */
diff --git a/include/grub/err.h b/include/grub/err.h
index 2edc514..0f9b208 100644
--- a/include/grub/err.h
+++ b/include/grub/err.h
@@ -69,7 +69,8 @@ typedef enum
GRUB_ERR_NET_UNKNOWN_ERROR,
GRUB_ERR_NET_PACKET_TOO_BIG,
GRUB_ERR_NET_NO_DOMAIN,
- GRUB_ERR_EOF
+ GRUB_ERR_EOF,
+ GRUB_ERR_BAD_SIGNATURE
}
grub_err_t;
diff --git a/include/grub/file.h b/include/grub/file.h
index e08ac2e..ae86401 100644
--- a/include/grub/file.h
+++ b/include/grub/file.h
@@ -54,6 +54,7 @@ typedef struct grub_file *grub_file_t;
/* Filters with lower ID are executed first. */
typedef enum grub_file_filter_id
{
+ GRUB_FILE_FILTER_PUBKEY,
GRUB_FILE_FILTER_GZIO,
GRUB_FILE_FILTER_XZIO,
GRUB_FILE_FILTER_LZOPIO,
@@ -62,7 +63,7 @@ typedef enum grub_file_filter_id
GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO,
} grub_file_filter_id_t;
-typedef grub_file_t (*grub_file_filter_t) (grub_file_t in);
+typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, const char *filename);
extern grub_file_filter_t EXPORT_VAR(grub_file_filters_all)[GRUB_FILE_FILTER_MAX];
extern grub_file_filter_t EXPORT_VAR(grub_file_filters_enabled)[GRUB_FILE_FILTER_MAX];
@@ -72,20 +73,20 @@ grub_file_filter_register (grub_file_filter_id_t id, grub_file_filter_t filter)
{
grub_file_filters_all[id] = filter;
grub_file_filters_enabled[id] = filter;
-};
+}
static inline void
grub_file_filter_unregister (grub_file_filter_id_t id)
{
grub_file_filters_all[id] = 0;
grub_file_filters_enabled[id] = 0;
-};
+}
static inline void
grub_file_filter_disable (grub_file_filter_id_t id)
{
grub_file_filters_enabled[id] = 0;
-};
+}
static inline void
grub_file_filter_disable_compression (void)
@@ -95,7 +96,23 @@ grub_file_filter_disable_compression (void)
for (id = GRUB_FILE_FILTER_COMPRESSION_FIRST;
id <= GRUB_FILE_FILTER_COMPRESSION_LAST; id++)
grub_file_filters_enabled[id] = 0;
-};
+}
+
+static inline void
+grub_file_filter_disable_all (void)
+{
+ grub_file_filter_id_t id;
+
+ for (id = 0;
+ id < GRUB_FILE_FILTER_MAX; id++)
+ grub_file_filters_enabled[id] = 0;
+}
+
+static inline void
+grub_file_filter_disable_pubkey (void)
+{
+ grub_file_filters_enabled[GRUB_FILE_FILTER_PUBKEY] = 0;
+}
/* Get a device name from NAME. */
char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
diff --git a/include/grub/fs.h b/include/grub/fs.h
index 503d1a9..e451797 100644
--- a/include/grub/fs.h
+++ b/include/grub/fs.h
@@ -41,6 +41,10 @@ struct grub_dirhook_info
grub_int32_t mtime;
};
+typedef int (*grub_fs_dir_hook_t) (const char *filename,
+ const struct grub_dirhook_info *info,
+ void *data);
+
/* Filesystem descriptor. */
struct grub_fs
{
@@ -53,8 +57,7 @@ struct grub_fs
/* Call HOOK with each file under DIR. */
grub_err_t (*dir) (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
- const struct grub_dirhook_info *info));
+ grub_fs_dir_hook_t hook, void *hook_data);
/* Open a file named NAME and initialize FILE. */
grub_err_t (*open) (struct grub_file *file, const char *name);
diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h
index 4838fca..e437d4c 100644
--- a/include/grub/fshelp.h
+++ b/include/grub/fshelp.h
@@ -38,24 +38,25 @@ enum grub_fshelp_filetype
GRUB_FSHELP_SYMLINK
};
+typedef int (*grub_fshelp_iterate_dir_hook_t) (const char *filename,
+ enum grub_fshelp_filetype filetype,
+ grub_fshelp_node_t node,
+ void *data);
+
/* Lookup the node PATH. The node ROOTNODE describes the root of the
directory tree. The node found is returned in FOUNDNODE, which is
either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to
iterate over all directory entries in the current node.
READ_SYMLINK is used to read the symlink if a node is a symlink.
EXPECTTYPE is the type node that is expected by the called, an
- error is generated if the node is not of the expected type. Make
- sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
- because GCC has a nasty bug when using regparm=3. */
+ error is generated if the node is not of the expected type. */
grub_err_t
EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
grub_fshelp_node_t rootnode,
grub_fshelp_node_t *foundnode,
int (*iterate_dir) (grub_fshelp_node_t dir,
- int NESTED_FUNC_ATTR
- (*hook) (const char *filename,
- enum grub_fshelp_filetype filetype,
- grub_fshelp_node_t node)),
+ grub_fshelp_iterate_dir_hook_t hook,
+ void *hook_data),
char *(*read_symlink) (grub_fshelp_node_t node),
enum grub_fshelp_filetype expect);
diff --git a/include/grub/gcry/types.h b/include/grub/gcry/types.h
new file mode 100644
index 0000000..892a204
--- /dev/null
+++ b/include/grub/gcry/types.h
@@ -0,0 +1,37 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GCRY_TYPES_HEADER
+#define GRUB_GCRY_TYPES_HEADER 1
+
+#include <grub/types.h>
+#include <grub/misc.h>
+
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+#define WORDS_BIGENDIAN
+#else
+#undef WORDS_BIGENDIAN
+#endif
+
+typedef grub_uint64_t u64;
+typedef grub_uint32_t u32;
+typedef grub_uint16_t u16;
+typedef grub_uint8_t byte;
+typedef grub_size_t size_t;
+
+#endif
diff --git a/include/grub/gcrypt/gpg-error.h b/include/grub/gcrypt/gpg-error.h
new file mode 100644
index 0000000..1e42502
--- /dev/null
+++ b/include/grub/gcrypt/gpg-error.h
@@ -0,0 +1,32 @@
+#ifndef GRUB_GPG_ERROR_H
+#define GRUB_GPG_ERROR_H 1
+
+#include <grub/crypto.h>
+typedef enum
+ {
+ GPG_ERR_SOURCE_USER_1
+ }
+ gpg_err_source_t;
+#define GPG_ERR_INLINE inline
+static inline int
+gpg_err_make (gpg_err_source_t source __attribute__ ((unused)), gpg_err_code_t code)
+{
+ return code;
+}
+
+static inline gpg_err_code_t
+gpg_err_code (gpg_error_t err)
+{
+ return err;
+}
+
+static inline gpg_err_source_t
+gpg_err_source (gpg_error_t err __attribute__ ((unused)))
+{
+ return GPG_ERR_SOURCE_USER_1;
+}
+
+gcry_err_code_t
+gpg_error_from_syserror (void);
+
+#endif
diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
index 83e3b31..4aaf1c4 100644
--- a/include/grub/gpt_partition.h
+++ b/include/grub/gpt_partition.h
@@ -80,8 +80,8 @@ struct grub_gpt_partentry
grub_err_t
grub_gpt_partition_map_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition));
+ grub_partition_iterate_hook_t hook,
+ void *hook_data);
#endif /* ! GRUB_GPT_PARTITION_HEADER */
diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h
index f22c211..5ee9f9e 100644
--- a/include/grub/i386/macho.h
+++ b/include/grub/i386/macho.h
@@ -23,6 +23,11 @@
#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007)
#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007)
+#ifdef __x86_64__
+#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x01000007)
+#else
+#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x00000007)
+#endif
struct grub_macho_thread32
{
diff --git a/include/grub/i386/pit.h b/include/grub/i386/pit.h
index ff9b9a6..e1c92cd 100644
--- a/include/grub/i386/pit.h
+++ b/include/grub/i386/pit.h
@@ -22,6 +22,84 @@
#include <grub/types.h>
#include <grub/err.h>
+enum
+ {
+ /* The PIT channel value ports. You can write to and read from them.
+ Do not mess with timer 0 or 1. */
+ GRUB_PIT_COUNTER_0 = 0x40,
+ GRUB_PIT_COUNTER_1 = 0x41,
+ GRUB_PIT_COUNTER_2 = 0x42,
+ /* The PIT control port. You can only write to it. Do not mess with
+ timer 0 or 1. */
+ GRUB_PIT_CTRL = 0x43,
+ /* The speaker port. */
+ GRUB_PIT_SPEAKER_PORT = 0x61,
+ };
+
+
+/* The speaker port. */
+enum
+ {
+ /* If 0, follow state of SPEAKER_DATA bit, otherwise enable output
+ from timer 2. */
+ GRUB_PIT_SPK_TMR2 = 0x01,
+ /* If SPEAKER_TMR2 is not set, this provides direct input into the
+ speaker. Otherwise, this enables or disables the output from the
+ timer. */
+ GRUB_PIT_SPK_DATA = 0x02,
+
+ GRUB_PIT_SPK_TMR2_LATCH = 0x20
+ };
+
+/* The PIT control port. You can only write to it. Do not mess with
+ timer 0 or 1. */
+enum
+ {
+ GRUB_PIT_CTRL_SELECT_MASK = 0xc0,
+ GRUB_PIT_CTRL_SELECT_0 = 0x00,
+ GRUB_PIT_CTRL_SELECT_1 = 0x40,
+ GRUB_PIT_CTRL_SELECT_2 = 0x80,
+
+ /* Read and load control. */
+ GRUB_PIT_CTRL_READLOAD_MASK= 0x30,
+ GRUB_PIT_CTRL_COUNTER_LATCH = 0x00, /* Hold timer value until read. */
+ GRUB_PIT_CTRL_READLOAD_LSB = 0x10, /* Read/load the LSB. */
+ GRUB_PIT_CTRL_READLOAD_MSB = 0x20, /* Read/load the MSB. */
+ GRUB_PIT_CTRL_READLOAD_WORD = 0x30, /* Read/load the LSB then the MSB. */
+
+ /* Mode control. */
+ GRUB_PIT_CTRL_MODE_MASK = 0x0e,
+ /* Interrupt on terminal count. Setting the mode sets output to low.
+ When counter is set and terminated, output is set to high. */
+ GRUB_PIT_CTRL_INTR_ON_TERM = 0x00,
+ /* Programmable one-shot. When loading counter, output is set to
+ high. When counter terminated, output is set to low. Can be
+ triggered again from that point on by setting the gate pin to
+ high. */
+ GRUB_PIT_CTRL_PROGR_ONE_SHOT = 0x02,
+
+ /* Rate generator. Output is low for one period of the counter, and
+ high for the other. */
+ GRUB_PIT_CTRL_RATE_GEN = 0x04,
+
+ /* Square wave generator. Output is low for one half of the period,
+ and high for the other half. */
+ GRUB_PIT_CTRL_SQUAREWAVE_GEN = 0x06,
+ /* Software triggered strobe. Setting the mode sets output to high.
+ When counter is set and terminated, output is set to low. */
+ GRUB_PIT_CTRL_SOFTSTROBE = 0x08,
+
+ /* Hardware triggered strobe. Like software triggered strobe, but
+ only starts the counter when the gate pin is set to high. */
+ GRUB_PIT_CTRL_HARDSTROBE = 0x0a,
+
+
+ /* Count mode. */
+ GRUB_PIT_CTRL_COUNT_MASK = 0x01,
+ GRUB_PIT_CTRL_COUNT_BINARY = 0x00, /* 16-bit binary counter. */
+ GRUB_PIT_CTRL_COUNT_BCD = 0x01 /* 4-decade BCD counter. */
+ };
+
void EXPORT_FUNC(grub_pit_wait) (grub_uint16_t tics);
#endif /* ! KERNEL_CPU_PIT_HEADER */
diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h
index 46becb8..5f89a7e 100644
--- a/include/grub/i386/relocator.h
+++ b/include/grub/i386/relocator.h
@@ -49,6 +49,7 @@ struct grub_relocator16_state
grub_uint32_t ebx;
grub_uint32_t edx;
grub_uint32_t esi;
+ grub_uint32_t ebp;
int a20;
};
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
index eef4c3f..23e4f02 100644
--- a/include/grub/kernel.h
+++ b/include/grub/kernel.h
@@ -27,7 +27,8 @@ enum
OBJ_TYPE_ELF,
OBJ_TYPE_MEMDISK,
OBJ_TYPE_CONFIG,
- OBJ_TYPE_PREFIX
+ OBJ_TYPE_PREFIX,
+ OBJ_TYPE_PUBKEY
};
/* The module header. */
@@ -77,7 +78,7 @@ extern grub_addr_t EXPORT_VAR (grub_modbase);
var && (grub_addr_t) var \
< (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \
var = (struct grub_module_header *) \
- ((grub_uint32_t *) var + ((struct grub_module_header *) var)->size / 4))
+ (((grub_uint32_t *) var) + ((((struct grub_module_header *) var)->size + sizeof (grub_addr_t) - 1) / sizeof (grub_addr_t)) * (sizeof (grub_addr_t) / sizeof (grub_uint32_t))))
grub_addr_t grub_modules_get_end (void);
diff --git a/include/grub/macho.h b/include/grub/macho.h
index 6a98b6e..21f0714 100644
--- a/include/grub/macho.h
+++ b/include/grub/macho.h
@@ -27,6 +27,7 @@ struct grub_macho_fat_header
grub_uint32_t nfat_arch;
} __attribute__ ((packed));
#define GRUB_MACHO_FAT_MAGIC 0xcafebabe
+#define GRUB_MACHO_FAT_EFI_MAGIC 0x0ef1fab9
typedef grub_uint32_t grub_macho_cpu_type_t;
typedef grub_uint32_t grub_macho_cpu_subtype_t;
diff --git a/include/grub/memory.h b/include/grub/memory.h
index 61470d7..3311fcb 100644
--- a/include/grub/memory.h
+++ b/include/grub/memory.h
@@ -36,21 +36,25 @@ typedef enum grub_memory_type
GRUB_MEMORY_HOLE = 21
} grub_memory_type_t;
-typedef int NESTED_FUNC_ATTR (*grub_memory_hook_t) (grub_uint64_t,
- grub_uint64_t,
- grub_memory_type_t);
+typedef int (*grub_memory_hook_t) (grub_uint64_t,
+ grub_uint64_t,
+ grub_memory_type_t,
+ void *);
-grub_err_t grub_mmap_iterate (grub_memory_hook_t hook);
+grub_err_t grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data);
#ifdef GRUB_MACHINE_EFI
grub_err_t
-grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services);
+grub_efi_mmap_iterate (grub_memory_hook_t hook, void *hook_data,
+ int avoid_efi_boot_services);
#endif
#if !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_EFI)
-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) (grub_memory_hook_t hook);
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) (grub_memory_hook_t hook,
+ void *hook_data);
#else
-grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook);
+grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook,
+ void *hook_data);
#endif
int grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type);
diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h
index 9c8ac3e..1e9b65e 100644
--- a/include/grub/msdos_partition.h
+++ b/include/grub/msdos_partition.h
@@ -120,7 +120,7 @@ grub_msdos_partition_is_extended (int type)
grub_err_t
grub_partition_msdos_iterate (grub_disk_t disk,
- int (*hook) (grub_disk_t disk,
- const grub_partition_t partition));
+ grub_partition_iterate_hook_t hook,
+ void *hook_data);
#endif /* ! GRUB_PC_PARTITION_HEADER */
diff --git a/include/grub/normal.h b/include/grub/normal.h
index e88cd26..416faa4 100644
--- a/include/grub/normal.h
+++ b/include/grub/normal.h
@@ -77,6 +77,14 @@ grub_print_ucs4 (const grub_uint32_t * str,
const grub_uint32_t * last_position,
int margin_left, int margin_right,
struct grub_term_output *term);
+
+void
+grub_print_ucs4_menu (const grub_uint32_t * str,
+ const grub_uint32_t * last_position,
+ int margin_left, int margin_right,
+ struct grub_term_output *term,
+ int skip_lines, int max_lines, grub_uint32_t contchar,
+ struct grub_term_pos *pos);
int
grub_ucs4_count_lines (const grub_uint32_t * str,
const grub_uint32_t * last_position,
diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h
index 0935342..37983c4 100644
--- a/include/grub/ntfs.h
+++ b/include/grub/ntfs.h
@@ -87,6 +87,7 @@ enum
#define GRUB_NTFS_COM_LEN 4096
#define GRUB_NTFS_COM_LOG_LEN 12
#define GRUB_NTFS_COM_SEC (GRUB_NTFS_COM_LEN >> GRUB_NTFS_BLK_SHR)
+#define GRUB_NTFS_LOG_COM_SEC (GRUB_NTFS_COM_LOG_LEN - GRUB_NTFS_BLK_SHR)
enum
{
@@ -131,17 +132,17 @@ struct grub_ntfs_bpb
struct grub_ntfs_attr
{
int flags;
- char *emft_buf, *edat_buf;
- char *attr_cur, *attr_nxt, *attr_end;
+ grub_uint8_t *emft_buf, *edat_buf;
+ grub_uint8_t *attr_cur, *attr_nxt, *attr_end;
grub_uint32_t save_pos;
- char *sbuf;
+ grub_uint8_t *sbuf;
struct grub_ntfs_file *mft;
};
struct grub_ntfs_file
{
struct grub_ntfs_data *data;
- char *buf;
+ grub_uint8_t *buf;
grub_uint64_t size;
grub_uint64_t mtime;
grub_uint32_t ino;
@@ -154,10 +155,10 @@ struct grub_ntfs_data
struct grub_ntfs_file cmft;
struct grub_ntfs_file mmft;
grub_disk_t disk;
- grub_uint32_t mft_size;
- grub_uint32_t idx_size;
- grub_uint32_t spc;
- grub_uint32_t mft_start;
+ grub_uint64_t mft_size;
+ grub_uint64_t idx_size;
+ int log_spc;
+ grub_uint64_t mft_start;
grub_uint64_t uuid;
};
@@ -172,21 +173,22 @@ struct grub_ntfs_comp
grub_disk_t disk;
int comp_head, comp_tail;
struct grub_ntfs_comp_table_element comp_table[16];
- grub_uint32_t cbuf_ofs, cbuf_vcn, spc;
- char *cbuf;
+ grub_uint32_t cbuf_ofs, cbuf_vcn;
+ int log_spc;
+ grub_uint8_t *cbuf;
};
struct grub_ntfs_rlst
{
int flags;
grub_disk_addr_t target_vcn, curr_vcn, next_vcn, curr_lcn;
- char *cur_run;
+ grub_uint8_t *cur_run;
struct grub_ntfs_attr *attr;
struct grub_ntfs_comp comp;
};
typedef grub_err_t (*grub_ntfscomp_func_t) (struct grub_ntfs_attr * at,
- char *dest,
+ grub_uint8_t *dest,
grub_disk_addr_t ofs,
grub_size_t len,
struct grub_ntfs_rlst * ctx,
diff --git a/include/grub/parser.h b/include/grub/parser.h
index de4da05..bf9c7c6 100644
--- a/include/grub/parser.h
+++ b/include/grub/parser.h
@@ -63,6 +63,7 @@ EXPORT_FUNC (grub_parser_cmdline_state) (grub_parser_state_t state,
grub_err_t
EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline,
grub_reader_getline_t getline,
+ void *getline_data,
int *argc, char ***argv);
struct grub_parser
@@ -79,13 +80,15 @@ struct grub_parser
/* Clean up the parser. */
grub_err_t (*fini) (void);
- grub_err_t (*parse_line) (char *line, grub_reader_getline_t getline);
+ grub_err_t (*parse_line) (char *line,
+ grub_reader_getline_t getline, void *getline_data);
};
typedef struct grub_parser *grub_parser_t;
grub_err_t grub_parser_execute (char *source);
grub_err_t
-grub_rescue_parse_line (char *line, grub_reader_getline_t getline);
+grub_rescue_parse_line (char *line,
+ grub_reader_getline_t getline, void *getline_data);
#endif /* ! GRUB_PARSER_HEADER */
diff --git a/include/grub/partition.h b/include/grub/partition.h
index ec0a667..7adb7ec 100644
--- a/include/grub/partition.h
+++ b/include/grub/partition.h
@@ -33,6 +33,10 @@ typedef enum
} grub_embed_type_t;
#endif
+typedef int (*grub_partition_iterate_hook_t) (struct grub_disk *disk,
+ const grub_partition_t partition,
+ void *data);
+
/* Partition map type. */
struct grub_partition_map
{
@@ -45,8 +49,7 @@ struct grub_partition_map
/* Call HOOK with each partition, until HOOK returns non-zero. */
grub_err_t (*iterate) (struct grub_disk *disk,
- int (*hook) (struct grub_disk *disk,
- const grub_partition_t partition));
+ grub_partition_iterate_hook_t hook, void *hook_data);
#ifdef GRUB_UTIL
/* Determine sectors available for embedding. */
grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors,
@@ -89,8 +92,8 @@ struct grub_partition
grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
const char *str);
int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk,
- int (*hook) (struct grub_disk *disk,
- const grub_partition_t partition));
+ grub_partition_iterate_hook_t hook,
+ void *hook_data);
char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
diff --git a/include/grub/pci.h b/include/grub/pci.h
index aaf0101..e163d47 100644
--- a/include/grub/pci.h
+++ b/include/grub/pci.h
@@ -132,13 +132,14 @@ grub_pci_get_function (grub_pci_device_t dev)
#include <grub/cpu/pci.h>
#endif
-typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t)
- (grub_pci_device_t dev, grub_pci_id_t pciid);
+typedef int (*grub_pci_iteratefunc_t)
+ (grub_pci_device_t dev, grub_pci_id_t pciid, void *data);
grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev,
int reg);
-void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook);
+void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook,
+ void *hook_data);
struct grub_pci_dma_chunk;
diff --git a/include/grub/pubkey.h b/include/grub/pubkey.h
new file mode 100644
index 0000000..4a9d04b
--- /dev/null
+++ b/include/grub/pubkey.h
@@ -0,0 +1,38 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PUBKEY_HEADER
+#define GRUB_PUBKEY_HEADER 1
+
+#include <grub/crypto.h>
+
+struct grub_public_key *
+grub_load_public_key (grub_file_t f);
+
+grub_err_t
+grub_verify_signature (grub_file_t f, grub_file_t sig,
+ struct grub_public_key *pk);
+
+
+struct grub_public_subkey *
+grub_crypto_pk_locate_subkey (grub_uint64_t keyid, struct grub_public_key *pkey);
+
+struct grub_public_subkey *
+grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid);
+
+#endif
diff --git a/include/grub/reader.h b/include/grub/reader.h
index cd92df8..fd86b20 100644
--- a/include/grub/reader.h
+++ b/include/grub/reader.h
@@ -22,7 +22,7 @@
#include <grub/err.h>
-typedef grub_err_t (*grub_reader_getline_t) (char **, int);
+typedef grub_err_t (*grub_reader_getline_t) (char **, int, void *);
void grub_rescue_run (void) __attribute__ ((noreturn));
diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
index d99cbf7..78602e4 100644
--- a/include/grub/script_sh.h
+++ b/include/grub/script_sh.h
@@ -161,6 +161,9 @@ struct grub_lexer_param
expected, but not available. */
grub_reader_getline_t getline;
+ /* Caller-supplied data passed to `getline'. */
+ void *getline_data;
+
/* A reference counter. If this is >0 it means that the parser
expects more tokens and `getline' should be called to fetch more.
Otherwise the lexer can stop processing if the current buffer is
@@ -287,14 +290,16 @@ grub_script_arg_add (struct grub_parser_param *state,
grub_script_arg_type_t type, char *str);
struct grub_script *grub_script_parse (char *script,
- grub_reader_getline_t getline);
+ grub_reader_getline_t getline,
+ void *getline_data);
void grub_script_free (struct grub_script *script);
struct grub_script *grub_script_create (struct grub_script_cmd *cmd,
struct grub_script_mem *mem);
struct grub_lexer_param *grub_script_lexer_init (struct grub_parser_param *parser,
char *script,
- grub_reader_getline_t getline);
+ grub_reader_getline_t getline,
+ void *getline_data);
void grub_script_lexer_fini (struct grub_lexer_param *);
void grub_script_lexer_ref (struct grub_lexer_param *);
void grub_script_lexer_deref (struct grub_lexer_param *);
@@ -380,7 +385,8 @@ char **
grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count);
grub_err_t
-grub_normal_parse_line (char *line, grub_reader_getline_t getline);
+grub_normal_parse_line (char *line,
+ grub_reader_getline_t getline, void *getline_data);
static inline struct grub_script *
grub_script_ref (struct grub_script *script)
diff --git a/include/grub/scsi.h b/include/grub/scsi.h
index 13300ca..a919a7c 100644
--- a/include/grub/scsi.h
+++ b/include/grub/scsi.h
@@ -49,10 +49,13 @@ grub_make_scsi_id (int subsystem, int bus, int lun)
| (bus << GRUB_SCSI_ID_BUS_SHIFT) | (lun << GRUB_SCSI_ID_LUN_SHIFT);
}
+typedef int (*grub_scsi_dev_iterate_hook_t) (int id, int bus, int luns,
+ void *data);
+
struct grub_scsi_dev
{
/* Call HOOK with each device name, until HOOK returns non-zero. */
- int (*iterate) (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns),
+ int (*iterate) (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
grub_disk_pull_t pull);
/* Open the device named NAME, and set up SCSI. */
diff --git a/include/grub/speaker.h b/include/grub/speaker.h
new file mode 100644
index 0000000..a076fcf
--- /dev/null
+++ b/include/grub/speaker.h
@@ -0,0 +1,47 @@
+#ifndef GRUB_SPEAKER_HEADER
+#define GRUB_SPEAKER_HEADER 1
+
+#include <grub/cpu/io.h>
+#include <grub/i386/pit.h>
+
+/* The frequency of the PIT clock. */
+#define GRUB_SPEAKER_PIT_FREQUENCY 0x1234dd
+
+static inline void
+grub_speaker_beep_off (void)
+{
+ unsigned char status;
+
+ status = grub_inb (GRUB_PIT_SPEAKER_PORT);
+ grub_outb (status & ~(GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA),
+ GRUB_PIT_SPEAKER_PORT);
+}
+
+static inline void
+grub_speaker_beep_on (grub_uint16_t pitch)
+{
+ unsigned char status;
+ unsigned int counter;
+
+ if (pitch < 20)
+ pitch = 20;
+ else if (pitch > 20000)
+ pitch = 20000;
+
+ counter = GRUB_SPEAKER_PIT_FREQUENCY / pitch;
+
+ /* Program timer 2. */
+ grub_outb (GRUB_PIT_CTRL_SELECT_2
+ | GRUB_PIT_CTRL_READLOAD_WORD
+ | GRUB_PIT_CTRL_SQUAREWAVE_GEN
+ | GRUB_PIT_CTRL_COUNT_BINARY, GRUB_PIT_CTRL);
+ grub_outb (counter & 0xff, GRUB_PIT_COUNTER_2); /* LSB */
+ grub_outb ((counter >> 8) & 0xff, GRUB_PIT_COUNTER_2); /* MSB */
+
+ /* Start speaker. */
+ status = grub_inb (GRUB_PIT_SPEAKER_PORT);
+ grub_outb (status | GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA,
+ GRUB_PIT_SPEAKER_PORT);
+}
+
+#endif
diff --git a/include/grub/symbol.h b/include/grub/symbol.h
index a2ba9b2..e2119bf 100644
--- a/include/grub/symbol.h
+++ b/include/grub/symbol.h
@@ -29,16 +29,16 @@
#if HAVE_ASM_USCORE
#ifdef ASM_FILE
-#ifndef (__arm__)
-#define EXT_C(sym) _ ## sym
+# ifndef (__arm__)
+# define EXT_C(sym) _ ## sym
+# else
+# define EXT_C(sym) % ## sym
+# endif
#else
-#define EXT_C(sym) % ## sym
+# define EXT_C(sym) "_" sym
#endif
#else
-#define EXT_C(sym) "_" sym
-#endif
-#else
-#define EXT_C(sym) sym
+# define EXT_C(sym) sym
#endif
#if defined (__APPLE__)
@@ -56,8 +56,8 @@
/* Mark an exported symbol. */
#ifndef GRUB_SYMBOL_GENERATOR
-#define EXPORT_FUNC(x) x
-#define EXPORT_VAR(x) x
+# define EXPORT_FUNC(x) x
+# define EXPORT_VAR(x) x
#endif /* ! GRUB_SYMBOL_GENERATOR */
#endif /* ! GRUB_SYMBOL_HEADER */
diff --git a/include/grub/term.h b/include/grub/term.h
index bf4dcb4..84f5766 100644
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -104,7 +104,7 @@ grub_term_color_state;
#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT)
/* UTF-8 stream in logical order. Usually used for terminals
which just forward the stream to another computer. */
-#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT)
+#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT)
/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */
#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT)
/* Glyph description in visual order. */
@@ -221,10 +221,6 @@ struct grub_term_output
/* The feature flags defined above. */
grub_uint32_t flags;
- /* Current color state. */
- grub_uint8_t normal_color;
- grub_uint8_t highlight_color;
-
void *data;
};
typedef struct grub_term_output *grub_term_output_t;
@@ -233,6 +229,10 @@ typedef struct grub_term_output *grub_term_output_t;
#define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70
#define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07
+/* Current color state. */
+extern grub_uint8_t EXPORT_VAR(grub_term_normal_color);
+extern grub_uint8_t EXPORT_VAR(grub_term_highlight_color);
+
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled);
extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled);
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
@@ -344,7 +344,7 @@ static inline unsigned grub_term_height (struct grub_term_output *term)
static inline unsigned
grub_term_border_width (struct grub_term_output *term)
{
- return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH;
+ return grub_term_width (term) - GRUB_TERM_MARGIN * 2;
}
/* The max column number of an entry. The last "-1" is for a
@@ -352,7 +352,7 @@ grub_term_border_width (struct grub_term_output *term)
static inline int
grub_term_entry_width (struct grub_term_output *term)
{
- return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1;
+ return grub_term_border_width (term) - GRUB_TERM_MARGIN * 2 - 1;
}
static inline grub_uint16_t
@@ -391,16 +391,6 @@ grub_setcolorstate (grub_term_color_state state)
grub_term_setcolorstate (term, state);
}
-/* Set the normal color and the highlight color. The format of each
- color is VGA's. */
-static inline void
-grub_term_setcolor (struct grub_term_output *term,
- grub_uint8_t normal_color, grub_uint8_t highlight_color)
-{
- term->normal_color = normal_color;
- term->highlight_color = highlight_color;
-}
-
/* Turn on/off the cursor. */
static inline void
grub_term_setcursor (struct grub_term_output *term, int on)
@@ -460,14 +450,6 @@ grub_term_getcharwidth (struct grub_term_output *term,
return 1;
}
-static inline void
-grub_term_getcolor (struct grub_term_output *term,
- grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
-{
- *normal_color = term->normal_color;
- *highlight_color = term->highlight_color;
-}
-
struct grub_term_autoload
{
struct grub_term_autoload *next;
diff --git a/include/grub/unicode.h b/include/grub/unicode.h
index 763e25e..eb5051a 100644
--- a/include/grub/unicode.h
+++ b/include/grub/unicode.h
@@ -139,6 +139,7 @@ struct grub_unicode_glyph
grub_uint16_t variant:9;
grub_uint8_t attributes:5;
grub_size_t ncomb;
+ grub_size_t orig_pos;
struct grub_unicode_combining {
grub_uint32_t code;
enum grub_comb_type type;
@@ -186,6 +187,13 @@ enum
GRUB_UNICODE_THAANA_SUKUN = 0x07b0,
GRUB_UNICODE_ZWNJ = 0x200c,
GRUB_UNICODE_ZWJ = 0x200d,
+ GRUB_UNICODE_LRM = 0x200e,
+ GRUB_UNICODE_RLM = 0x200f,
+ GRUB_UNICODE_LRE = 0x202a,
+ GRUB_UNICODE_RLE = 0x202b,
+ GRUB_UNICODE_PDF = 0x202c,
+ GRUB_UNICODE_LRO = 0x202d,
+ GRUB_UNICODE_RLO = 0x202e,
GRUB_UNICODE_LEFTARROW = 0x2190,
GRUB_UNICODE_UPARROW = 0x2191,
GRUB_UNICODE_RIGHTARROW = 0x2192,
@@ -222,13 +230,21 @@ extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[];
/* Unicode mandates an arbitrary limit. */
#define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61
+struct grub_term_pos
+{
+ unsigned valid:1;
+ unsigned x:15, y:16;
+};
+
grub_ssize_t
grub_bidi_logical_to_visual (const grub_uint32_t *logical,
grub_size_t logical_len,
struct grub_unicode_glyph **visual_out,
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
grub_size_t max_width,
- grub_size_t start_width);
+ grub_size_t start_width, grub_uint32_t codechar,
+ struct grub_term_pos *pos,
+ int primitive_wrap);
enum grub_comb_type
grub_unicode_get_comb_type (grub_uint32_t c);
@@ -275,4 +291,8 @@ grub_unicode_mirror_code (grub_uint32_t in);
grub_uint32_t
grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr);
+const grub_uint32_t *
+grub_unicode_get_comb_end (const grub_uint32_t *end,
+ const grub_uint32_t *cur);
+
#endif
diff --git a/include/grub/usb.h b/include/grub/usb.h
index 08d57b2..cefa8b6 100644
--- a/include/grub/usb.h
+++ b/include/grub/usb.h
@@ -50,8 +50,12 @@ typedef enum
GRUB_USB_SPEED_HIGH
} grub_usb_speed_t;
+typedef int (*grub_usb_iterate_hook_t) (grub_usb_device_t dev, void *data);
+typedef int (*grub_usb_controller_iterate_hook_t) (grub_usb_controller_t dev,
+ void *data);
+
/* Call HOOK with each device, until HOOK returns non-zero. */
-int grub_usb_iterate (int (*hook) (grub_usb_device_t dev));
+int grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data);
grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev);
@@ -72,7 +76,8 @@ void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb);
void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb);
-int grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev));
+int grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook,
+ void *hook_data);
grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
@@ -98,7 +103,7 @@ struct grub_usb_controller_dev
/* The device name. */
const char *name;
- int (*iterate) (int (*hook) (grub_usb_controller_t dev));
+ int (*iterate) (grub_usb_controller_iterate_hook_t hook, void *hook_data);
grub_usb_err_t (*setup_transfer) (grub_usb_controller_t dev,
grub_usb_transfer_t transfer);
diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h
index 5ee276d..5429007 100644
--- a/include/grub/usbtrans.h
+++ b/include/grub/usbtrans.h
@@ -19,6 +19,8 @@
#ifndef GRUB_USBTRANS_H
#define GRUB_USBTRANS_H 1
+#define MAX_USB_TRANSFER_LEN 0x0800
+
typedef enum
{
GRUB_USB_TRANSFER_TYPE_IN,
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index f5650cd..d3edb42 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -35,9 +35,9 @@ AC_DEFUN([gl_STDIO_H],
dnl Check for declarations of anything we want to poison if the
dnl corresponding gnulib module is not in use, and which is not
- dnl guaranteed by C89.
+ dnl guaranteed by both C89 and C11.
gl_WARN_ON_USE_PREPARE([[#include <stdio.h>
- ]], [dprintf fpurge fseeko ftello getdelim getline popen renameat
+ ]], [dprintf fpurge fseeko ftello getdelim getline gets popen renameat
snprintf tmpfile vdprintf vsnprintf])
])
diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in
index 80c8830..5adce0a 100644
--- a/tests/util/grub-shell-tester.in
+++ b/tests/util/grub-shell-tester.in
@@ -18,8 +18,6 @@ set -e
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in
index f4fa23a..04e64da 100644
--- a/tests/util/grub-shell.in
+++ b/tests/util/grub-shell.in
@@ -18,8 +18,6 @@ set -e
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in
index 64d49fe..44bf135 100644
--- a/util/bash-completion.d/grub-completion.bash.in
+++ b/util/bash-completion.d/grub-completion.bash.in
@@ -165,12 +165,12 @@ _grub_set_entry () {
fi
}
-__grub_set_default_program=$( echo grub-set-default | sed "@program_transform_name@" )
+__grub_set_default_program="@grub_set_default@"
have ${__grub_set_default_program} && \
complete -F _grub_set_entry -o filenames ${__grub_set_default_program}
unset __grub_set_default_program
-__grub_reboot_program=$( echo grub-reboot | sed "@program_transform_name@" )
+__grub_reboot_program="@grub_reboot@"
have ${__grub_reboot_program} && \
complete -F _grub_set_entry -o filenames ${__grub_reboot_program}
unset __grub_reboot_program
@@ -197,7 +197,7 @@ _grub_editenv () {
create list set unset"
}
-__grub_editenv_program=$( echo grub-editenv | sed "@program_transform_name@" )
+__grub_editenv_program="@grub_editenv@"
have ${__grub_editenv_program} && \
complete -F _grub_editenv -o filenames ${__grub_editenv_program}
unset __grub_editenv_program
@@ -218,7 +218,7 @@ _grub_mkconfig () {
_filedir
fi
}
-__grub_mkconfig_program=$( echo grub-mkconfig | sed "@program_transform_name@" )
+__grub_mkconfig_program="@grub_mkconfig@"
have ${__grub_mkconfig_program} && \
complete -F _grub_mkconfig -o filenames ${__grub_mkconfig_program}
unset __grub_mkconfig_program
@@ -252,10 +252,16 @@ _grub_setup () {
_filedir
fi
}
-__grub_setup_program=$( echo grub-setup | sed "@program_transform_name@" )
-have ${__grub_setup_program} && \
- complete -F _grub_setup -o filenames ${__grub_setup_program}
-unset __grub_setup_program
+
+__grub_bios_setup_program="@grub_bios_setup@"
+have ${__grub_bios_setup_program} && \
+ complete -F _grub_setup -o filenames ${__grub_bios_setup_program}
+unset __grub_bios_setup_program
+
+__grub_sparc64_setup_program="@grub_sparc64_setup@"
+have ${__grub_sparc64_setup_program} && \
+ complete -F _grub_setup -o filenames ${__grub_sparc64_setup_program}
+unset __grub_sparc64_setup_program
#
@@ -298,7 +304,7 @@ _grub_install () {
_filedir
fi
}
-__grub_install_program=$( echo grub-install | sed "@program_transform_name@" )
+__grub_install_program="@grub_install@"
have ${__grub_install_program} && \
complete -F _grub_install -o filenames ${__grub_install_program}
unset __grub_install_program
@@ -320,7 +326,7 @@ _grub_mkfont () {
_filedir
fi
}
-__grub_mkfont_program=$( echo grub-mkfont | sed "@program_transform_name@" )
+__grub_mkfont_program="@grub_mkfont@"
have ${__grub_mkfont_program} && \
complete -F _grub_mkfont -o filenames ${__grub_mkfont_program}
unset __grub_mkfont_program
@@ -351,7 +357,7 @@ _grub_mkrescue () {
_filedir
fi
}
-__grub_mkrescue_program=$( echo grub-mkrescue | sed "@program_transform_name@" )
+__grub_mkrescue_program="@grub_mkrescue@"
have ${__grub_mkrescue_program} && \
complete -F _grub_mkrescue -o filenames ${__grub_mkrescue_program}
unset __grub_mkrescue_program
@@ -393,7 +399,7 @@ _grub_mkimage () {
_filedir
fi
}
-__grub_mkimage_program=$( echo grub-mkimage | sed "@program_transform_name@" )
+__grub_mkimage_program="@grub_mkimage@"
have ${__grub_mkimage_program} && \
complete -F _grub_mkimage -o filenames ${__grub_mkimage_program}
unset __grub_mkimage_program
@@ -415,7 +421,7 @@ _grub_mkpasswd_pbkdf2 () {
_filedir
fi
}
-__grub_mkpasswd_pbkdf2_program=$( echo grub-mkpasswd-pbkdf2 | sed "@program_transform_name@" )
+__grub_mkpasswd_pbkdf2_program="@grub_mkpasswd_pbkdf2@"
have ${__grub_mkpasswd_pbkdf2_program} && \
complete -F _grub_mkpasswd_pbkdf2 -o filenames ${__grub_mkpasswd_pbkdf2_program}
unset __grub_mkpasswd_pbkdf2_program
@@ -453,7 +459,7 @@ _grub_probe () {
_filedir
fi
}
-__grub_probe_program=$( echo grub-probe | sed "@program_transform_name@" )
+__grub_probe_program="@grub_probe@"
have ${__grub_probe_program} && \
complete -F _grub_probe -o filenames ${__grub_probe_program}
unset __grub_probe_program
@@ -475,7 +481,7 @@ _grub_script_check () {
_filedir
fi
}
-__grub_script_check_program=$( echo grub-script-check | sed "@program_transform_name@" )
+__grub_script_check_program="@grub_script_check@"
have ${__grub_script_check_program} && \
complete -F _grub_script_check -o filenames ${__grub_script_check_program}
diff --git a/util/getroot.c b/util/getroot.c
index 24ce6aa..654d1e1 100644
--- a/util/getroot.c
+++ b/util/getroot.c
@@ -1065,7 +1065,7 @@ grub_guess_root_devices (const char *dir)
{
*cur = canonicalize_file_name (tmp);
if (*cur == NULL)
- grub_util_error (_("failed to get canonical path of %s"), tmp);
+ grub_util_error (_("failed to get canonical path of `%s'"), tmp);
free (tmp);
}
root = (strcmp (*cur, "/dev/root") == 0);
@@ -2198,6 +2198,36 @@ grub_util_get_os_disk (const char *os_dev)
return convert_system_partition_to_system_disk (os_dev, &st, &is_part);
}
+#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__sun__)
+/* Context for grub_util_biosdisk_get_grub_dev. */
+struct grub_util_biosdisk_get_grub_dev_ctx
+{
+ char *partname;
+ grub_disk_addr_t start;
+};
+
+/* Helper for grub_util_biosdisk_get_grub_dev. */
+static int
+find_partition (grub_disk_t dsk __attribute__ ((unused)),
+ const grub_partition_t partition, void *data)
+{
+ struct grub_util_biosdisk_get_grub_dev_ctx *ctx = data;
+ grub_disk_addr_t part_start = 0;
+ grub_util_info ("Partition %d starts from %" PRIuGRUB_UINT64_T,
+ partition->number, partition->start);
+
+ part_start = grub_partition_get_start (partition);
+
+ if (ctx->start == part_start)
+ {
+ ctx->partname = grub_partition_get_name (partition);
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
char *
grub_util_biosdisk_get_grub_dev (const char *os_dev)
{
@@ -2250,29 +2280,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
For NetBSD and FreeBSD, proceed as for Linux, except that the start
sector is obtained from the disk label. */
{
- char *name, *partname;
+ char *name;
grub_disk_t disk;
- grub_disk_addr_t start;
- auto int find_partition (grub_disk_t dsk,
- const grub_partition_t partition);
-
- int find_partition (grub_disk_t dsk __attribute__ ((unused)),
- const grub_partition_t partition)
- {
- grub_disk_addr_t part_start = 0;
- grub_util_info ("Partition %d starts from %" PRIuGRUB_UINT64_T,
- partition->number, partition->start);
-
- part_start = grub_partition_get_start (partition);
-
- if (start == part_start)
- {
- partname = grub_partition_get_name (partition);
- return 1;
- }
-
- return 0;
- }
+ struct grub_util_biosdisk_get_grub_dev_ctx ctx;
name = make_device_name (drive, -1, -1);
@@ -2284,16 +2294,16 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
* different, we know that os_dev cannot be a floppy device. */
# endif /* !defined(HAVE_DIOCGDINFO) */
- start = grub_hostdisk_find_partition_start (os_dev);
+ ctx.start = grub_hostdisk_find_partition_start (os_dev);
if (grub_errno != GRUB_ERR_NONE)
{
free (name);
return 0;
}
- grub_util_info ("%s starts from %" PRIuGRUB_UINT64_T, os_dev, start);
+ grub_util_info ("%s starts from %" PRIuGRUB_UINT64_T, os_dev, ctx.start);
- if (start == 0 && !is_part)
+ if (ctx.start == 0 && !is_part)
return name;
grub_util_info ("opening the device %s", name);
@@ -2325,20 +2335,20 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return 0;
}
- name = grub_util_get_ldm (disk, start);
+ name = grub_util_get_ldm (disk, ctx.start);
if (name)
return name;
- partname = NULL;
+ ctx.partname = NULL;
- grub_partition_iterate (disk, find_partition);
+ grub_partition_iterate (disk, find_partition, &ctx);
if (grub_errno != GRUB_ERR_NONE)
{
grub_disk_close (disk);
return 0;
}
- if (partname == NULL)
+ if (ctx.partname == NULL)
{
grub_disk_close (disk);
grub_util_info ("cannot find the partition of `%s'", os_dev);
@@ -2347,8 +2357,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return 0;
}
- name = grub_xasprintf ("%s,%s", disk->name, partname);
- free (partname);
+ name = grub_xasprintf ("%s,%s", disk->name, ctx.partname);
+ free (ctx.partname);
grub_disk_close (disk);
return name;
}
@@ -2778,7 +2788,7 @@ grub_make_system_path_relative_to_its_root (const char *path)
/* canonicalize. */
p = canonicalize_file_name (path);
if (p == NULL)
- grub_util_error (_("failed to get canonical path of %s"), path);
+ grub_util_error (_("failed to get canonical path of `%s'"), path);
/* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */
#if !defined (__MINGW32__) && !defined (__CYGWIN__)
diff --git a/util/grub-install.in b/util/grub-install.in
index 6754da0..9b7d243 100644
--- a/util/grub-install.in
+++ b/util/grub-install.in
@@ -17,8 +17,6 @@
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
@@ -44,10 +42,10 @@ localedir="@datadir@/locale"
self="`basename $0`"
-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`"
-grub_probe="${sbindir}/`echo grub-probe | sed ${transform}`"
-grub_editenv="${bindir}/`echo grub-editenv | sed ${transform}`"
-grub_mkrelpath="${bindir}/`echo grub-mkrelpath | sed ${transform}`"
+grub_mkimage="${bindir}/@grub_mkimage@"
+grub_probe="${sbindir}/@grub_probe@"
+grub_editenv="${bindir}/@grub_editenv@"
+grub_mkrelpath="${bindir}/@grub_mkrelpath@"
rootdir=
bootdir=
grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`"
@@ -116,8 +114,8 @@ echo
gettext "INSTALL_DEVICE must be system device filename.";echo
echo
-gettext_printf "%s copies GRUB images into %s, and uses grub-setup
-to install grub into the boot sector.\n" "$self" "$grubdir";echo
+gettext_printf "%s copies GRUB images into %s. On some platforms, it
+may also install GRUB into the boot sector.\n" "$self" "$grubdir";echo
echo
gettext "Report bugs to <bug-grub@gnu.org>."; echo
}
@@ -349,11 +347,11 @@ else
fi
if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ]; then
- grub_setup="${sbindir}/`echo grub-bios-setup | sed ${transform}`"
+ grub_setup="${sbindir}/@grub_bios_setup@"
fi
if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ]; then
- grub_setup="${sbindir}/`echo grub-sparc64-setup | sed ${transform}`"
+ grub_setup="${sbindir}/@grub_sparc64_setup@"
fi
if test "x$install_device" = x && ([ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] \
@@ -509,7 +507,7 @@ if test $recheck = yes; then
rm -f "$device_map"
fi
-# Create the device map file if it is not present.
+# Device map file is optional
if test -f "$device_map"; then
# Make sure that there is no duplicated entry.
tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' "$device_map" \
diff --git a/util/grub-kbdcomp.in b/util/grub-kbdcomp.in
index 29f0456..715c483 100644
--- a/util/grub-kbdcomp.in
+++ b/util/grub-kbdcomp.in
@@ -1,7 +1,5 @@
#!/bin/sh
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
bindir="@bindir@"
@@ -11,7 +9,7 @@ if [ "x$pkgdatadir" = x ]; then
pkgdatadir="${datadir}/@PACKAGE@"
fi
-grub_mklayout="${bindir}/`echo grub-mklayout | sed ${transform}`"
+grub_mklayout="${bindir}/@grub_mklayout@"
ckbcomp_options=""
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index 516be86..8decc1d 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -17,7 +17,6 @@ set -e
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
-transform="@program_transform_name@"
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
@@ -39,9 +38,9 @@ grub_mkconfig_dir="${sysconfdir}"/grub.d
self=`basename $0`
-grub_probe="${sbindir}/`echo grub-probe | sed "${transform}"`"
-grub_editenv="${bindir}/`echo grub-editenv | sed "${transform}"`"
-grub_script_check="${bindir}/`echo grub-script-check | sed "${transform}"`"
+grub_probe="${sbindir}/@grub_probe@"
+grub_editenv="${bindir}/@grub_editenv@"
+grub_script_check="${bindir}/@grub_script_check@"
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR="@localedir@"
@@ -159,7 +158,7 @@ fi
for x in ${GRUB_TERMINAL_OUTPUT}; do
case "x${x}" in
xgfxterm) ;;
- xconsole | xserial | xofconsole)
+ xconsole | xserial | xofconsole | xvga_text)
# make sure all our children behave in conformance with ascii..
export LANG=C;;
*) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;;
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
index 3574839..e560dd7 100644
--- a/util/grub-mkconfig_lib.in
+++ b/util/grub-mkconfig_lib.in
@@ -14,8 +14,6 @@
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
@@ -25,10 +23,10 @@ sbindir="@sbindir@"
pkgdatadir="${datadir}/@PACKAGE@"
if test "x$grub_probe" = x; then
- grub_probe="${sbindir}/`echo grub-probe | sed "${transform}"`"
+ grub_probe="${sbindir}/@grub_probe@"
fi
if test "x$grub_mkrelpath" = x; then
- grub_mkrelpath="${bindir}/`echo grub-mkrelpath | sed "${transform}"`"
+ grub_mkrelpath="${bindir}/@grub_mkrelpath@"
fi
if which gettext >/dev/null 2>/dev/null; then
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
index e1de710..3e98c00 100644
--- a/util/grub-mkimage.c
+++ b/util/grub-mkimage.c
@@ -69,7 +69,7 @@ struct image_target_desc
IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275,
IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH,
IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC,
- IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT,
+ IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT
} id;
enum
{
@@ -720,8 +720,8 @@ struct fixup_block_list
static void
generate_image (const char *dir, const char *prefix,
FILE *out, const char *outname, char *mods[],
- char *memdisk_path, char *config_path,
- struct image_target_desc *image_target, int note,
+ char *memdisk_path, char **pubkey_paths, size_t npubkeys,
+ char *config_path, struct image_target_desc *image_target, int note,
grub_compression_t comp)
{
char *kernel_img, *core_img;
@@ -753,6 +753,18 @@ generate_image (const char *dir, const char *prefix,
else
total_module_size = sizeof (struct grub_module_info32);
+ {
+ size_t i;
+ for (i = 0; i < npubkeys; i++)
+ {
+ size_t curs;
+ curs = ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i]));
+ grub_util_info ("the size of public key %zd is 0x%llx",
+ i, (unsigned long long) curs);
+ total_module_size += curs + sizeof (struct grub_module_header);
+ }
+ }
+
if (memdisk_path)
{
memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
@@ -854,6 +866,26 @@ generate_image (const char *dir, const char *prefix,
offset += mod_size;
}
+ {
+ size_t i;
+ for (i = 0; i < npubkeys; i++)
+ {
+ size_t curs;
+ struct grub_module_header *header;
+
+ curs = grub_util_get_image_size (pubkey_paths[i]);
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ memset (header, 0, sizeof (struct grub_module_header));
+ header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY);
+ header->size = grub_host_to_target32 (curs + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (pubkey_paths[i], kernel_img + offset);
+ offset += ALIGN_ADDR (curs);
+ }
+ }
+
if (memdisk_path)
{
struct grub_module_header *header;
@@ -1648,7 +1680,7 @@ generate_image (const char *dir, const char *prefix,
case IMAGE_UBOOT:
/* Raw image, header added by grub-install */
break;
- }
+ }
grub_util_write_image (core_img, core_size, out, outname);
free (core_img);
@@ -1676,6 +1708,8 @@ static struct argp_option options[] = {
N_("embed FILE as a memdisk image"), 0},
/* TRANSLATORS: "embed" is a verb (command description). "*/
{"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0},
+ /* TRANSLATORS: "embed" is a verb (command description). "*/
+ {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0},
/* TRANSLATORS: NOTE is a name of segment. */
{"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0},
{"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
@@ -1731,6 +1765,8 @@ struct arguments
char *dir;
char *prefix;
char *memdisk;
+ char **pubkeys;
+ size_t npubkeys;
char *font;
char *config;
int note;
@@ -1793,6 +1829,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
arguments->prefix = xstrdup ("(memdisk)/boot/grub");
break;
+ case 'k':
+ arguments->pubkeys = xrealloc (arguments->pubkeys,
+ sizeof (arguments->pubkeys[0])
+ * (arguments->npubkeys + 1));
+ arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg);
+ break;
+
case 'c':
if (arguments->config)
free (arguments->config);
@@ -1900,7 +1943,8 @@ main (int argc, char *argv[])
generate_image (arguments.dir, arguments.prefix ? : DEFAULT_DIRECTORY, fp,
arguments.output,
- arguments.modules, arguments.memdisk, arguments.config,
+ arguments.modules, arguments.memdisk, arguments.pubkeys,
+ arguments.npubkeys, arguments.config,
arguments.image_target, arguments.note, arguments.comp);
fflush (fp);
diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in
index d1ad763..e235af3 100644
--- a/util/grub-mknetdir.in
+++ b/util/grub-mknetdir.in
@@ -17,8 +17,6 @@
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
@@ -36,7 +34,7 @@ fi
self=`basename $0`
-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`"
+grub_mkimage="${bindir}/@grub_mkimage@"
rootdir=/srv/tftp
modules=
diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in
index f71099e..d279a9d 100644
--- a/util/grub-mkrescue.in
+++ b/util/grub-mkrescue.in
@@ -19,8 +19,6 @@ set -e
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
@@ -49,7 +47,7 @@ efi64_dir="${libdir}/@PACKAGE@/x86_64-efi"
ia64_dir="${libdir}/@PACKAGE@/ia64-efi"
rom_directory=
override_dir=
-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`"
+grub_mkimage="${bindir}/@grub_mkimage@"
xorriso=xorriso
diff --git a/util/grub-mkstandalone.in b/util/grub-mkstandalone.in
index 87a3b42..78b83e0 100644
--- a/util/grub-mkstandalone.in
+++ b/util/grub-mkstandalone.in
@@ -19,8 +19,6 @@ set -e
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
@@ -40,7 +38,7 @@ self=`basename $0`
source_directory=
compression=auto
format=
-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`"
+grub_mkimage="${bindir}/@grub_mkimage@"
source=
export TEXTDOMAIN=@PACKAGE@
diff --git a/util/grub-mount.c b/util/grub-mount.c
index e3eb1d7..d0ab6a2 100644
--- a/util/grub-mount.c
+++ b/util/grub-mount.c
@@ -116,30 +116,38 @@ translate_error (void)
return ret;
}
+/* Context for fuse_getattr. */
+struct fuse_getattr_ctx
+{
+ char *filename;
+ struct grub_dirhook_info file_info;
+ int file_exists;
+};
+
+/* A hook for iterating directories. */
+static int
+fuse_getattr_find_file (const char *cur_filename,
+ const struct grub_dirhook_info *info, void *data)
+{
+ struct fuse_getattr_ctx *ctx = data;
+
+ if ((info->case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename)
+ : grub_strcmp (cur_filename, ctx->filename)) == 0)
+ {
+ ctx->file_info = *info;
+ ctx->file_exists = 1;
+ return 1;
+ }
+ return 0;
+}
+
static int
fuse_getattr (const char *path, struct stat *st)
{
- char *filename, *pathname, *path2;
+ struct fuse_getattr_ctx ctx;
+ char *pathname, *path2;
const char *pathname_t;
- struct grub_dirhook_info file_info;
- int file_exists = 0;
- /* A hook for iterating directories. */
- auto int find_file (const char *cur_filename,
- const struct grub_dirhook_info *info);
- int find_file (const char *cur_filename,
- const struct grub_dirhook_info *info)
- {
- if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename)
- : grub_strcmp (cur_filename, filename)) == 0)
- {
- file_info = *info;
- file_exists = 1;
- return 1;
- }
- return 0;
- }
-
if (path[0] == '/' && path[1] == 0)
{
st->st_dev = 0;
@@ -155,7 +163,7 @@ fuse_getattr (const char *path, struct stat *st)
return 0;
}
- file_exists = 0;
+ ctx.file_exists = 0;
pathname_t = grub_strchr (path, ')');
if (! pathname_t)
@@ -169,35 +177,35 @@ fuse_getattr (const char *path, struct stat *st)
pathname[grub_strlen (pathname) - 1] = 0;
/* Split into path and filename. */
- filename = grub_strrchr (pathname, '/');
- if (! filename)
+ ctx.filename = grub_strrchr (pathname, '/');
+ if (! ctx.filename)
{
path2 = grub_strdup ("/");
- filename = pathname;
+ ctx.filename = pathname;
}
else
{
- filename++;
+ ctx.filename++;
path2 = grub_strdup (pathname);
- path2[filename - pathname] = 0;
+ path2[ctx.filename - pathname] = 0;
}
/* It's the whole device. */
- (fs->dir) (dev, path2, find_file);
+ (fs->dir) (dev, path2, fuse_getattr_find_file, &ctx);
grub_free (path2);
- if (!file_exists)
+ if (!ctx.file_exists)
{
grub_errno = GRUB_ERR_NONE;
return -ENOENT;
}
st->st_dev = 0;
st->st_ino = 0;
- st->st_mode = file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG);
+ st->st_mode = ctx.file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG);
st->st_uid = 0;
st->st_gid = 0;
st->st_rdev = 0;
- if (!file_info.dir)
+ if (!ctx.file_info.dir)
{
grub_file_t file;
file = grub_file_open (path);
@@ -210,8 +218,8 @@ fuse_getattr (const char *path, struct stat *st)
st->st_size = 0;
st->st_blksize = 512;
st->st_blocks = (st->st_size + 511) >> 9;
- st->st_atime = st->st_mtime = st->st_ctime = file_info.mtimeset
- ? file_info.mtime : 0;
+ st->st_atime = st->st_mtime = st->st_ctime = ctx.file_info.mtimeset
+ ? ctx.file_info.mtime : 0;
grub_errno = GRUB_ERR_NONE;
return 0;
}
@@ -271,39 +279,55 @@ fuse_release (const char *path, struct fuse_file_info *fi)
return 0;
}
+/* Context for fuse_readdir. */
+struct fuse_readdir_ctx
+{
+ const char *path;
+ void *buf;
+ fuse_fill_dir_t fill;
+};
+
+/* Helper for fuse_readdir. */
+static int
+fuse_readdir_call_fill (const char *filename,
+ const struct grub_dirhook_info *info, void *data)
+{
+ struct fuse_readdir_ctx *ctx = data;
+ struct stat st;
+
+ grub_memset (&st, 0, sizeof (st));
+ st.st_mode = info->dir ? (0555 | S_IFDIR) : (0444 | S_IFREG);
+ if (!info->dir)
+ {
+ grub_file_t file;
+ char *tmp;
+ tmp = xasprintf ("%s/%s", ctx->path, filename);
+ file = grub_file_open (tmp);
+ free (tmp);
+ if (! file)
+ return translate_error ();
+ st.st_size = file->size;
+ grub_file_close (file);
+ }
+ st.st_blksize = 512;
+ st.st_blocks = (st.st_size + 511) >> 9;
+ st.st_atime = st.st_mtime = st.st_ctime
+ = info->mtimeset ? info->mtime : 0;
+ ctx->fill (ctx->buf, filename, &st, 0);
+ return 0;
+}
+
static int
fuse_readdir (const char *path, void *buf,
fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi)
{
+ struct fuse_readdir_ctx ctx = {
+ .path = path,
+ .buf = buf,
+ .fill = fill
+ };
char *pathname;
- auto int call_fill (const char *filename,
- const struct grub_dirhook_info *info);
- int call_fill (const char *filename, const struct grub_dirhook_info *info)
- {
- struct stat st;
- grub_memset (&st, 0, sizeof (st));
- st.st_mode = info->dir ? (0555 | S_IFDIR) : (0444 | S_IFREG);
- if (!info->dir)
- {
- grub_file_t file;
- char *tmp;
- tmp = xasprintf ("%s/%s", path, filename);
- file = grub_file_open (tmp);
- free (tmp);
- if (! file)
- return translate_error ();
- st.st_size = file->size;
- grub_file_close (file);
- }
- st.st_blksize = 512;
- st.st_blocks = (st.st_size + 511) >> 9;
- st.st_atime = st.st_mtime = st.st_ctime
- = info->mtimeset ? info->mtime : 0;
- fill (buf, filename, &st, 0);
- return 0;
- }
-
pathname = xstrdup (path);
/* Remove trailing '/'. */
@@ -311,7 +335,7 @@ fuse_readdir (const char *path, void *buf,
&& pathname[grub_strlen (pathname) - 1] == '/')
pathname[grub_strlen (pathname) - 1] = 0;
- (fs->dir) (dev, pathname, call_fill);
+ (fs->dir) (dev, pathname, fuse_readdir_call_fill, &ctx);
free (pathname);
grub_errno = GRUB_ERR_NONE;
return 0;
diff --git a/util/grub-probe.c b/util/grub-probe.c
index c2a0f62..b66cbea 100644
--- a/util/grub-probe.c
+++ b/util/grub-probe.c
@@ -327,7 +327,7 @@ probe (const char *path, char **device_names, char delim)
{
grub_path = canonicalize_file_name (path);
if (! grub_path)
- grub_util_error (_("failed to get canonical path of %s"), path);
+ grub_util_error (_("failed to get canonical path of `%s'"), path);
device_names = grub_guess_root_devices (grub_path);
free (grub_path);
}
diff --git a/util/grub-reboot.in b/util/grub-reboot.in
index 93dbe6c..1a91d36 100644
--- a/util/grub-reboot.in
+++ b/util/grub-reboot.in
@@ -17,11 +17,10 @@
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
+sysconfdir="@sysconfdir@"
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
datarootdir="@datarootdir@"
@@ -32,7 +31,7 @@ fi
self=`basename $0`
-grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}`
+grub_editenv=${bindir}/@grub_editenv@
rootdir=
bootdir=
grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
@@ -47,6 +46,7 @@ export TEXTDOMAINDIR="@localedir@"
usage () {
gettext_printf "Usage: %s [OPTION] MENU_ENTRY\n" "$self"
gettext "Set the default boot menu entry for GRUB, for the next boot only."; echo
+ gettext_printf "This requires setting GRUB_DEFAULT=saved in %s/default/grub.\n" "$sysconfdir"
echo
print_option_help "-h, --help" "$(gettext "print this message and exit")"
print_option_help "-v, --version" "$(gettext "print the version information and exit")"
diff --git a/util/grub-script-check.c b/util/grub-script-check.c
index 73d51f0..48c772a 100644
--- a/util/grub-script-check.c
+++ b/util/grub-script-check.c
@@ -85,81 +85,92 @@ static struct argp argp = {
NULL, NULL, NULL
};
+/* Context for main. */
+struct main_ctx
+{
+ int lineno;
+ FILE *file;
+ struct arguments arguments;
+};
+
+/* Helper for main. */
+static grub_err_t
+get_config_line (char **line, int cont __attribute__ ((unused)), void *data)
+{
+ struct main_ctx *ctx = data;
+ int i;
+ char *cmdline = 0;
+ size_t len = 0;
+ ssize_t curread;
+
+ curread = getline (&cmdline, &len, (ctx->file ?: stdin));
+ if (curread == -1)
+ {
+ *line = 0;
+ grub_errno = GRUB_ERR_READ_ERROR;
+
+ if (cmdline)
+ free (cmdline);
+ return grub_errno;
+ }
+
+ if (ctx->arguments.verbose)
+ grub_printf ("%s", cmdline);
+
+ for (i = 0; cmdline[i] != '\0'; i++)
+ {
+ /* Replace tabs and carriage returns with spaces. */
+ if (cmdline[i] == '\t' || cmdline[i] == '\r')
+ cmdline[i] = ' ';
+
+ /* Replace '\n' with '\0'. */
+ if (cmdline[i] == '\n')
+ cmdline[i] = '\0';
+ }
+
+ ctx->lineno++;
+ *line = grub_strdup (cmdline);
+
+ free (cmdline);
+ return 0;
+}
+
int
main (int argc, char *argv[])
{
+ struct main_ctx ctx = {
+ .lineno = 0,
+ .file = 0
+ };
char *input;
- int lineno = 0;
- FILE *file = 0;
- struct arguments arguments;
int found_input = 0;
struct grub_script *script = NULL;
- auto grub_err_t get_config_line (char **line, int cont);
- grub_err_t get_config_line (char **line, int cont __attribute__ ((unused)))
- {
- int i;
- char *cmdline = 0;
- size_t len = 0;
- ssize_t curread;
-
- curread = getline(&cmdline, &len, (file ?: stdin));
- if (curread == -1)
- {
- *line = 0;
- grub_errno = GRUB_ERR_READ_ERROR;
-
- if (cmdline)
- free (cmdline);
- return grub_errno;
- }
-
- if (arguments.verbose)
- grub_printf("%s", cmdline);
-
- for (i = 0; cmdline[i] != '\0'; i++)
- {
- /* Replace tabs and carriage returns with spaces. */
- if (cmdline[i] == '\t' || cmdline[i] == '\r')
- cmdline[i] = ' ';
-
- /* Replace '\n' with '\0'. */
- if (cmdline[i] == '\n')
- cmdline[i] = '\0';
- }
-
- lineno++;
- *line = grub_strdup (cmdline);
-
- free (cmdline);
- return 0;
- }
-
set_program_name (argv[0]);
grub_util_init_nls ();
- memset (&arguments, 0, sizeof (struct arguments));
+ memset (&ctx.arguments, 0, sizeof (struct arguments));
/* Check for options. */
- if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
+ if (argp_parse (&argp, argc, argv, 0, 0, &ctx.arguments) != 0)
{
fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
exit(1);
}
/* Obtain ARGUMENT. */
- if (!arguments.filename)
+ if (!ctx.arguments.filename)
{
- file = 0; /* read from stdin */
+ ctx.file = 0; /* read from stdin */
}
else
{
- file = fopen (arguments.filename, "r");
- if (! file)
+ ctx.file = fopen (ctx.arguments.filename, "r");
+ if (! ctx.file)
{
char *program = xstrdup(program_name);
- fprintf (stderr, "%s: %s: %s\n", program_name,
- arguments.filename, strerror(errno));
+ fprintf (stderr, _("cannot open `%s': %s"),
+ ctx.arguments.filename, strerror (errno));
argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
free(program);
exit(1);
@@ -169,12 +180,12 @@ main (int argc, char *argv[])
do
{
input = 0;
- get_config_line(&input, 0);
+ get_config_line (&input, 0, &ctx);
if (! input)
break;
found_input = 1;
- script = grub_script_parse (input, get_config_line);
+ script = grub_script_parse (input, get_config_line, &ctx);
if (script)
{
grub_script_execute (script);
@@ -184,11 +195,11 @@ main (int argc, char *argv[])
grub_free (input);
} while (script != 0);
- if (file) fclose (file);
+ if (ctx.file) fclose (ctx.file);
if (found_input && script == 0)
{
- fprintf (stderr, _("Syntax error at line %u\n"), lineno);
+ fprintf (stderr, _("Syntax error at line %u\n"), ctx.lineno);
return 1;
}
diff --git a/util/grub-set-default.in b/util/grub-set-default.in
index 3d890be..ea18da1 100644
--- a/util/grub-set-default.in
+++ b/util/grub-set-default.in
@@ -17,11 +17,10 @@
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
+sysconfdir="@sysconfdir@"
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
datarootdir="@datarootdir@"
@@ -32,7 +31,7 @@ fi
self=`basename $0`
-grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}`
+grub_editenv=${bindir}/@grub_editenv@
rootdir=
bootdir=
grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
@@ -47,6 +46,7 @@ export TEXTDOMAINDIR="@localedir@"
usage () {
gettext_printf "Usage: %s [OPTION] MENU_ENTRY\n" "$self"
gettext "Set the default boot menu entry for GRUB."; echo
+ gettext_printf "This requires setting GRUB_DEFAULT=saved in %s/default/grub.\n" "$sysconfdir"
echo
print_option_help "-h, --help" "$(gettext "print this message and exit")"
print_option_help "-v, --version" "$(gettext "print the version information and exit")"
diff --git a/util/grub-setup.c b/util/grub-setup.c
index de0417f..187345a 100644
--- a/util/grub-setup.c
+++ b/util/grub-setup.c
@@ -138,6 +138,44 @@ write_rootdev (grub_device_t root_dev,
#define BOOT_SECTOR 0
#endif
+#ifdef GRUB_SETUP_BIOS
+/* Context for setup/identify_partmap. */
+struct identify_partmap_ctx
+{
+ grub_partition_map_t dest_partmap;
+ grub_partition_t container;
+ int multiple_partmaps;
+};
+
+/* Helper for setup/identify_partmap.
+ Unlike root_dev, with dest_dev we're interested in the partition map even
+ if dest_dev itself is a whole disk. */
+static int
+identify_partmap (grub_disk_t disk __attribute__ ((unused)),
+ const grub_partition_t p, void *data)
+{
+ struct identify_partmap_ctx *ctx = data;
+
+ if (p->parent != ctx->container)
+ return 0;
+ /* NetBSD and OpenBSD subpartitions have metadata inside a partition,
+ so they are safe to ignore.
+ */
+ if (grub_strcmp (p->partmap->name, "netbsd") == 0
+ || grub_strcmp (p->partmap->name, "openbsd") == 0)
+ return 0;
+ if (ctx->dest_partmap == NULL)
+ {
+ ctx->dest_partmap = p->partmap;
+ return 0;
+ }
+ if (ctx->dest_partmap == p->partmap)
+ return 0;
+ ctx->multiple_partmaps = 1;
+ return 1;
+}
+#endif
+
static void
setup (const char *dir,
const char *boot_file, const char *core_file,
@@ -337,9 +375,11 @@ setup (const char *dir,
#ifdef GRUB_SETUP_BIOS
{
- grub_partition_map_t dest_partmap = NULL;
- grub_partition_t container = dest_dev->disk->partition;
- int multiple_partmaps = 0;
+ struct identify_partmap_ctx ctx = {
+ .dest_partmap = NULL,
+ .container = dest_dev->disk->partition,
+ .multiple_partmaps = 0
+ };
int is_ldm;
grub_err_t err;
grub_disk_addr_t *sectors;
@@ -347,38 +387,13 @@ setup (const char *dir,
grub_fs_t fs;
unsigned int nsec, maxsec;
- /* Unlike root_dev, with dest_dev we're interested in the partition map even
- if dest_dev itself is a whole disk. */
- auto int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk,
- const grub_partition_t p);
- int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)),
- const grub_partition_t p)
- {
- if (p->parent != container)
- return 0;
- /* NetBSD and OpenBSD subpartitions have metadata inside a partition,
- so they are safe to ignore.
- */
- if (grub_strcmp (p->partmap->name, "netbsd") == 0
- || grub_strcmp (p->partmap->name, "openbsd") == 0)
- return 0;
- if (dest_partmap == NULL)
- {
- dest_partmap = p->partmap;
- return 0;
- }
- if (dest_partmap == p->partmap)
- return 0;
- multiple_partmaps = 1;
- return 1;
- }
-
- grub_partition_iterate (dest_dev->disk, identify_partmap);
+ grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx);
- if (container && grub_strcmp (container->partmap->name, "msdos") == 0
- && dest_partmap
- && (container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD
- || container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD))
+ if (ctx.container
+ && grub_strcmp (ctx.container->partmap->name, "msdos") == 0
+ && ctx.dest_partmap
+ && (ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD
+ || ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD))
{
grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet."));
goto unable_to_embed;
@@ -392,7 +407,7 @@ setup (const char *dir,
if (fs_probe)
{
- if (!fs && !dest_partmap)
+ if (!fs && !ctx.dest_partmap)
grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"),
dest_dev->disk->name);
if (fs && !fs->reserved_first_sector)
@@ -403,20 +418,20 @@ setup (const char *dir,
"by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"), dest_dev->disk->name, fs->name);
- if (dest_partmap && strcmp (dest_partmap->name, "msdos") != 0
- && strcmp (dest_partmap->name, "gpt") != 0
- && strcmp (dest_partmap->name, "bsd") != 0
- && strcmp (dest_partmap->name, "netbsd") != 0
- && strcmp (dest_partmap->name, "openbsd") != 0
- && strcmp (dest_partmap->name, "sunpc") != 0)
+ if (ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0
+ && strcmp (ctx.dest_partmap->name, "gpt") != 0
+ && strcmp (ctx.dest_partmap->name, "bsd") != 0
+ && strcmp (ctx.dest_partmap->name, "netbsd") != 0
+ && strcmp (ctx.dest_partmap->name, "openbsd") != 0
+ && strcmp (ctx.dest_partmap->name, "sunpc") != 0)
/* TRANSLATORS: Partition map may reserve the space just GRUB isn't sure about it. */
grub_util_error (_("%s appears to contain a %s partition map which isn't known to "
"reserve space for DOS-style boot. Installing GRUB there could "
"result in FILESYSTEM DESTRUCTION if valuable data is overwritten "
"by grub-setup (--skip-fs-probe disables this "
- "check, use at your own risk)"), dest_dev->disk->name, dest_partmap->name);
- if (is_ldm && dest_partmap && strcmp (dest_partmap->name, "msdos") != 0
- && strcmp (dest_partmap->name, "gpt") != 0)
+ "check, use at your own risk)"), dest_dev->disk->name, ctx.dest_partmap->name);
+ if (is_ldm && ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0
+ && strcmp (ctx.dest_partmap->name, "gpt") != 0)
grub_util_error (_("%s appears to contain a %s partition map and "
"LDM which isn't known to be a safe combination."
" Installing GRUB there could "
@@ -424,12 +439,12 @@ setup (const char *dir,
" is overwritten "
"by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"),
- dest_dev->disk->name, dest_partmap->name);
+ dest_dev->disk->name, ctx.dest_partmap->name);
}
/* Copy the partition table. */
- if (dest_partmap ||
+ if (ctx.dest_partmap ||
(!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)))
memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
@@ -437,21 +452,21 @@ setup (const char *dir,
free (tmp_img);
- if (! dest_partmap && ! fs && !is_ldm)
+ if (! ctx.dest_partmap && ! fs && !is_ldm)
{
grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea."));
goto unable_to_embed;
}
- if (multiple_partmaps || (dest_partmap && fs) || (is_ldm && fs))
+ if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && fs))
{
grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet."));
goto unable_to_embed;
}
- if (dest_partmap && !dest_partmap->embed)
+ if (ctx.dest_partmap && !ctx.dest_partmap->embed)
{
grub_util_warn (_("Partition style `%s' doesn't support embedding"),
- dest_partmap->name);
+ ctx.dest_partmap->name);
goto unable_to_embed;
}
@@ -473,9 +488,9 @@ setup (const char *dir,
if (is_ldm)
err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
GRUB_EMBED_PCBIOS, &sectors);
- else if (dest_partmap)
- err = dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
- GRUB_EMBED_PCBIOS, &sectors);
+ else if (ctx.dest_partmap)
+ err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
+ GRUB_EMBED_PCBIOS, &sectors);
else
err = fs->embed (dest_dev, &nsec, maxsec,
GRUB_EMBED_PCBIOS, &sectors);
@@ -507,12 +522,12 @@ setup (const char *dir,
grub_util_error ("%s", _("no terminator in the core image"));
}
- save_first_sector (sectors[0] + grub_partition_get_start (container),
+ save_first_sector (sectors[0] + grub_partition_get_start (ctx.container),
0, GRUB_DISK_SECTOR_SIZE);
block = first_block;
for (i = 1; i < nsec; i++)
- save_blocklists (sectors[i] + grub_partition_get_start (container),
+ save_blocklists (sectors[i] + grub_partition_get_start (ctx.container),
0, GRUB_DISK_SECTOR_SIZE);
/* Make sure that the last blocklist is a terminator. */
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
index 765bfdc..3da5d12 100644
--- a/util/grub.d/00_header.in
+++ b/util/grub.d/00_header.in
@@ -17,8 +17,6 @@ set -e
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in
index 260dda8..c123ceb 100644
--- a/util/grub.d/10_kfreebsd.in
+++ b/util/grub.d/10_kfreebsd.in
@@ -54,7 +54,7 @@ load_kfreebsd_module ()
fi
if [ -z "${prepare_module_dir_cache}" ]; then
- prepare_module_dir_cache="$(prepare_grub_to_access_device $(grub-probe -t device "${module_dir}") | grub_add_tab)"
+ prepare_module_dir_cache="$(prepare_grub_to_access_device $(${grub_probe} -t device "${module_dir}") | grub_add_tab)"
fi
printf '%s\n' "${prepare_module_dir_cache}"
@@ -112,7 +112,7 @@ EOF
load_kfreebsd_module acpi true
- for abstraction in dummy $(grub-probe -t abstraction --device ${GRUB_DEVICE}) ; do
+ for abstraction in dummy $(${grub_probe} -t abstraction --device ${GRUB_DEVICE}) ; do
case $abstraction in
lvm) load_kfreebsd_module geom_linux_lvm false ;;
esac
@@ -122,10 +122,10 @@ EOF
zfs)
load_kfreebsd_module opensolaris false
- ls "${dirname}/zfs/zpool.cache" > /dev/null
+ ls "/boot/zfs/zpool.cache" > /dev/null
printf '%s\n' "${prepare_boot_cache}"
sed "s/^/$submenu_indentation/" << EOF
- kfreebsd_module ${rel_dirname}/zfs/zpool.cache type=/boot/zfs/zpool.cache
+ kfreebsd_module $(make_system_path_relative_to_its_root /boot)/zfs/zpool.cache type=/boot/zfs/zpool.cache
EOF
;;
esac
@@ -179,7 +179,7 @@ while [ "x$list" != "x" ] ; do
case ${GRUB_FS} in
zfs)
# zpool name
- kfreebsd_device=$(grub-probe -t fs_label --device ${GRUB_DEVICE})
+ kfreebsd_device=$(${grub_probe} -t fs_label --device ${GRUB_DEVICE})
# filesystem name (empty string for the main filesystem)
kfreebsd_device="${kfreebsd_device}$(${grub_mkrelpath} / | sed -e "s,/*@$,,")"
;;
diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c
index 9de9ffc..f0a34b5 100644
--- a/util/ieee1275/ofpath.c
+++ b/util/ieee1275/ofpath.c
@@ -131,7 +131,7 @@ find_obppath (const char *sysfs_path_orig)
kill_trailing_dir(sysfs_path);
if (!strcmp(sysfs_path, "/sys"))
{
- grub_util_info (_("'obppath' not found in parent dirs of %s,"
+ grub_util_info (_("`obppath' not found in parent dirs of `%s',"
" no IEEE1275 name discovery"),
sysfs_path_orig);
free (path);
@@ -164,7 +164,7 @@ xrealpath (const char *in)
out = realpath (in, NULL);
#endif
if (!out)
- grub_util_error (_("failed to get canonical path of %s"), in);
+ grub_util_error (_("failed to get canonical path of `%s'"), in);
return out;
}
diff --git a/util/import_gcry.py b/util/import_gcry.py
index 64c5870..18f5253 100644
--- a/util/import_gcry.py
+++ b/util/import_gcry.py
@@ -39,6 +39,17 @@ try:
os.makedirs (cipher_dir_out)
except:
print ("WARNING: %s already exists" % cipher_dir_out)
+mpidir = os.path.join (basedir, "mpi")
+try:
+ os.makedirs (mpidir)
+except:
+ print ("WARNING: %s already exists" % mpidir)
+
+srcdir = os.path.join (basedir, "src")
+try:
+ os.makedirs (srcdir)
+except:
+ print ("WARNING: %s already exists" % srcdir)
cipher_files = sorted (os.listdir (cipher_dir_in))
conf = codecs.open (os.path.join ("grub-core", "Makefile.gcry.def"), "w", "utf-8")
@@ -52,7 +63,7 @@ confutil.write (" cppflags = '$(CPPFLAGS_GCRY)';\n");
confutil.write (" extra_dist = grub-core/lib/libgcrypt-grub/cipher/ChangeLog;\n");
confutil.write ("\n");
chlog = ""
-modules = []
+modules_sym_md = []
# Strictly speaking CRC32/CRC24 work on bytes so this value should be 1
# But libgcrypt uses 64. Let's keep the value for compatibility. Since
@@ -69,6 +80,8 @@ mdblocksizes = {"_gcry_digest_spec_crc32" : 64,
"_gcry_digest_spec_sha384" : 128,
"_gcry_digest_spec_sha512" : 128,
"_gcry_digest_spec_tiger" : 64,
+ "_gcry_digest_spec_tiger1" : 64,
+ "_gcry_digest_spec_tiger2" : 64,
"_gcry_digest_spec_whirlpool" : 64}
cryptolist = codecs.open (os.path.join (cipher_dir_out, "crypto.lst"), "w", "utf-8")
@@ -92,7 +105,7 @@ for cipher_file in cipher_files:
if cipher_file == "ChangeLog":
continue
chlognew = " * %s" % cipher_file
- if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file):
+ if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file) or cipher_file == "elgamal.c" or cipher_file == "primegen.c" or cipher_file == "test-getrusage.c":
chlog = "%s%s: Removed\n" % (chlog, chlognew)
continue
# Autogenerated files. Not even worth mentionning in ChangeLog
@@ -124,10 +137,12 @@ for cipher_file in cipher_files:
ciphernames = []
mdnames = []
+ pknames = []
hold = False
skip = False
skip2 = False
ismd = False
+ ispk = False
iscipher = False
iscryptostart = False
iscomma = False
@@ -159,7 +174,7 @@ for cipher_file in cipher_files:
sg = s.groups()[0]
cryptolist.write (("%s: %s\n") % (sg, modname))
iscryptostart = False
- if ismd or iscipher:
+ if ismd or iscipher or ispk:
if not re.search (" *};", line) is None:
if not iscomma:
fw.write (" ,\n")
@@ -175,6 +190,7 @@ for cipher_file in cipher_files:
% mdblocksizes [mdname])
ismd = False
iscipher = False
+ ispk = False
iscomma = not re.search (",$", line) is None
# Used only for selftests.
m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line)
@@ -190,18 +206,33 @@ for cipher_file in cipher_files:
continue
if hold:
hold = False
- # We're optimising for size.
- if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info|_gcry_rmd160_mixblock|serpent_test)", line) is None:
+ # We're optimising for size and exclude anything needing good
+ # randomness.
+ if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info|_gcry_rmd160_mixblock|serpent_test|dsa_generate_ext|test_keys|gen_k|sign|gen_x931_parm_xp|generate_x931|generate_key|dsa_generate|dsa_sign|ecc_sign|generate|generate_fips186|_gcry_register_pk_dsa_progress|_gcry_register_pk_ecc_progress|progress|scanval|ec2os|ecc_generate_ext|ecc_generate|compute_keygrip|ecc_get_param|_gcry_register_pk_dsa_progress|gen_x931_parm_xp|gen_x931_parm_xi|rsa_decrypt|rsa_sign|rsa_generate_ext|rsa_generate|secret|check_exponent|rsa_blind|rsa_unblind|extract_a_from_sexp|curve_free|curve_copy|point_set)", line) is None:
skip = True
if not re.match ("serpent_test", line) is None:
fw.write ("static const char *serpent_test (void) { return 0; }\n");
+ if not re.match ("dsa_generate", line) is None:
+ fw.write ("#define dsa_generate 0");
+ if not re.match ("ecc_generate", line) is None:
+ fw.write ("#define ecc_generate 0");
+ if not re.match ("rsa_generate ", line) is None:
+ fw.write ("#define rsa_generate 0");
+ if not re.match ("rsa_sign", line) is None:
+ fw.write ("#define rsa_sign 0");
+ if not re.match ("rsa_decrypt", line) is None:
+ fw.write ("#define rsa_decrypt 0");
+ if not re.match ("dsa_sign", line) is None:
+ fw.write ("#define dsa_sign 0");
+ if not re.match ("ecc_sign", line) is None:
+ fw.write ("#define ecc_sign 0");
fname = re.match ("[a-zA-Z0-9_]*", line).group ()
chmsg = "(%s): Removed." % fname
if nch:
chlognew = "%s\n %s" % (chlognew, chmsg)
else:
chlognew = "%s %s" % (chlognew, chmsg)
- nch = True
+ nch = True
continue
else:
fw.write (holdline)
@@ -216,7 +247,8 @@ for cipher_file in cipher_files:
continue
m = re.match ("gcry_cipher_spec_t", line)
if isc and not m is None:
- assert (not iscryptostart)
+ assert (not ismd)
+ assert (not ispk)
assert (not iscipher)
assert (not iscryptostart)
ciphername = line [len ("gcry_cipher_spec_t"):].strip ()
@@ -224,9 +256,23 @@ for cipher_file in cipher_files:
ciphernames.append (ciphername)
iscipher = True
iscryptostart = True
+
+ m = re.match ("gcry_pk_spec_t", line)
+ if isc and not m is None:
+ assert (not ismd)
+ assert (not ispk)
+ assert (not iscipher)
+ assert (not iscryptostart)
+ pkname = line [len ("gcry_pk_spec_t"):].strip ()
+ pkname = re.match("[a-zA-Z0-9_]*",pkname).group ()
+ pknames.append (pkname)
+ ispk = True
+ iscryptostart = True
+
m = re.match ("gcry_md_spec_t", line)
if isc and not m is None:
assert (not ismd)
+ assert (not ispk)
assert (not iscipher)
assert (not iscryptostart)
mdname = line [len ("gcry_md_spec_t"):].strip ()
@@ -245,7 +291,53 @@ for cipher_file in cipher_files:
chlognew = "%s %s" % (chlognew, chmsg)
nch = True
continue
- m = re.match ("(static const char( |)\*|static gpg_err_code_t|void|static int|static gcry_err_code_t)$", line)
+ m = re.match ("static gcry_mpi_t gen_k .*;$", line)
+ if not m is None:
+ chmsg = "(gen_k): Removed declaration."
+ if nch:
+ chlognew = "%s\n %s" % (chlognew, chmsg)
+ else:
+ chlognew = "%s %s" % (chlognew, chmsg)
+ nch = True
+ continue
+ m = re.match ("static (int|void) test_keys .*;$", line)
+ if not m is None:
+ chmsg = "(test_keys): Removed declaration."
+ if nch:
+ chlognew = "%s\n %s" % (chlognew, chmsg)
+ else:
+ chlognew = "%s %s" % (chlognew, chmsg)
+ nch = True
+ continue
+ m = re.match ("static void secret .*;$", line)
+ if not m is None:
+ chmsg = "(secret): Removed declaration."
+ if nch:
+ chlognew = "%s\n %s" % (chlognew, chmsg)
+ else:
+ chlognew = "%s %s" % (chlognew, chmsg)
+ nch = True
+ continue
+ m = re.match ("static void \(\*progress_cb\).*;$", line)
+ if not m is None:
+ chmsg = "(progress_cb): Removed declaration."
+ if nch:
+ chlognew = "%s\n %s" % (chlognew, chmsg)
+ else:
+ chlognew = "%s %s" % (chlognew, chmsg)
+ nch = True
+ continue
+ m = re.match ("static void \*progress_cb_data.*;$", line)
+ if not m is None:
+ chmsg = "(progress_cb): Removed declaration."
+ if nch:
+ chlognew = "%s\n %s" % (chlognew, chmsg)
+ else:
+ chlognew = "%s %s" % (chlognew, chmsg)
+ nch = True
+ continue
+
+ m = re.match ("(static const char( |)\*|static gpg_err_code_t|void|static int|static gcry_err_code_t|static gcry_mpi_t|static void|void|static elliptic_curve_t) *$", line)
if not m is None:
hold = True
holdline = line
@@ -257,6 +349,12 @@ for cipher_file in cipher_files:
if not m is None:
skip_statement = True
continue
+ m = re.match ("static void sign|static gpg_err_code_t sign|static gpg_err_code_t generate",
+ line)
+ if not m is None:
+ skip_statement = True
+ continue
+
m = re.match ("cipher_extra_spec_t", line)
if isc and not m is None:
skip2 = True
@@ -269,6 +367,18 @@ for cipher_file in cipher_files:
chlognew = "%s %s" % (chlognew, chmsg)
nch = True
continue
+ m = re.match ("pk_extra_spec_t", line)
+ if isc and not m is None:
+ skip2 = True
+ fname = line[len ("pk_extra_spec_t "):]
+ fname = re.match ("[a-zA-Z0-9_]*", fname).group ()
+ chmsg = "(%s): Removed." % fname
+ if nch:
+ chlognew = "%s\n %s" % (chlognew, chmsg)
+ else:
+ chlognew = "%s %s" % (chlognew, chmsg)
+ nch = True
+ continue
m = re.match ("md_extra_spec_t", line)
if isc and not m is None:
skip2 = True
@@ -282,13 +392,14 @@ for cipher_file in cipher_files:
nch = True
continue
fw.write (line)
- if len (ciphernames) > 0 or len (mdnames) > 0:
+ if len (ciphernames) > 0 or len (mdnames) > 0 or len (pknames) > 0:
if isglue:
modfiles = "lib/libgcrypt-grub/cipher/%s lib/libgcrypt-grub/cipher/%s" \
% (cipher_file, cipher_file.replace ("-glue.c", ".c"))
else:
modfiles = "lib/libgcrypt-grub/cipher/%s" % cipher_file
- modules.append (modname)
+ if len (ciphernames) > 0 or len (mdnames) > 0:
+ modules_sym_md.append (modname)
chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname
if nch:
chlognew = "%s\n %s" % (chlognew, chmsg)
@@ -305,6 +416,11 @@ for cipher_file in cipher_files:
chmsg = "Register digest %s" % mdname
chlognew = "%s\n %s" % (chlognew, chmsg)
fw.write (" grub_md_register (&%s);\n" % mdname)
+ for pkname in pknames:
+ chmsg = "Register pk %s" % mdname
+ chlognew = "%s\n %s" % (chlognew, chmsg)
+ fw.write (" grub_crypto_pk_%s = &%s;\n"
+ % (pkname.replace ("_gcry_pubkey_spec_", ""), pkname))
fw.write ("}")
chmsg = "(GRUB_MOD_FINI(%s)): New function\n" % modname
chlognew = "%s\n %s" % (chlognew, chmsg)
@@ -318,13 +434,22 @@ for cipher_file in cipher_files:
chmsg = "Unregister MD %s" % mdname
chlognew = "%s\n %s" % (chlognew, chmsg)
fw.write (" grub_md_unregister (&%s);\n" % mdname)
+ for pkname in pknames:
+ chmsg = "Unregister pk %s" % mdname
+ chlognew = "%s\n %s" % (chlognew, chmsg)
+ fw.write (" grub_crypto_pk_%s = 0;\n"
+ % (pkname.replace ("_gcry_pubkey_spec_", "")))
fw.write ("}\n")
conf.write ("module = {\n")
conf.write (" name = %s;\n" % modname)
for src in modfiles.split():
conf.write (" common = %s;\n" % src)
- confutil.write (" common = grub-core/%s;\n" % src)
- if modname == "gcry_rijndael" or modname == "gcry_md4" or modname == "gcry_md5" or modname == "gcry_rmd160" or modname == "gcry_sha1" or modname == "gcry_sha256" or modname == "gcry_sha512" or modname == "gcry_tiger":
+ if len (ciphernames) > 0 or len (mdnames) > 0:
+ confutil.write (" common = grub-core/%s;\n" % src)
+ if modname == "gcry_ecc":
+ conf.write (" common = lib/libgcrypt-grub/mpi/ec.c;\n")
+ conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';\n")
+ elif modname == "gcry_rijndael" or modname == "gcry_md4" or modname == "gcry_md5" or modname == "gcry_rmd160" or modname == "gcry_sha1" or modname == "gcry_sha256" or modname == "gcry_sha512" or modname == "gcry_tiger":
# Alignment checked by hand
conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-cast-align -Wno-strict-aliasing';\n");
else:
@@ -346,6 +471,62 @@ for cipher_file in cipher_files:
print ("WARNING: unknown file %s" % cipher_file)
cryptolist.close ()
+
+for src in sorted (os.listdir (os.path.join (indir, "src"))):
+ if src == "versioninfo.rc.in":
+ continue
+ outfile = os.path.join (basedir, "src", src)
+ infile = os.path.join (indir, "src", src)
+ if os.path.isdir (infile):
+ continue
+ fw = codecs.open (outfile, "w", "utf-8")
+ if src == "gcrypt-module.h":
+ fw.close ()
+ continue
+ if src == "visibility.h":
+ fw.write ("# include <grub/gcrypt/gcrypt.h>")
+ fw.close ()
+ continue
+ f = codecs.open (infile, "r", "utf-8")
+ fw.write (f.read ())
+ f.close ()
+ fw.close ()
+
+for src in sorted (os.listdir (os.path.join (indir, "mpi"))):
+ infile = os.path.join (indir, "mpi", src)
+ outfile = os.path.join (basedir, "mpi", src)
+ if os.path.isdir (infile):
+ continue
+ f = codecs.open (infile, "r", "utf-8")
+ fw = codecs.open (outfile, "w", "utf-8")
+ fw.write ("/* This file was automatically imported with \n")
+ fw.write (" import_gcry.py. Please don't modify it */\n")
+ hold = False
+ skip = False
+ for line in f:
+ if skip:
+ if line[0] == "}":
+ skip = False
+ continue
+ if hold:
+ hold = False
+ # We're optimising for size and exclude anything needing good
+ # randomness.
+ if not re.match ("(_gcry_mpi_get_hw_config|gcry_mpi_randomize)", line) is None:
+ skip = True
+ continue
+ else:
+ fw.write (holdline)
+ m = re.match ("(const char( |)\*|void) *$", line)
+ if not m is None:
+ hold = True
+ holdline = line
+ continue
+ m = re.match ("#include \"mod-source-info\.h\"", line)
+ if not m is None:
+ continue
+ fw.write (line)
+
chlog = "%s * crypto.lst: New file.\n" % chlog
outfile = os.path.join (cipher_dir_out, "types.h")
@@ -382,21 +563,21 @@ conf.close ();
initfile = codecs.open (os.path.join (cipher_dir_out, "init.c"), "w", "utf-8")
initfile.write ("#include <grub/crypto.h>\n")
-for module in modules:
+for module in modules_sym_md:
initfile.write ("extern void grub_%s_init (void);\n" % module)
initfile.write ("extern void grub_%s_fini (void);\n" % module)
initfile.write ("\n")
initfile.write ("void\n")
initfile.write ("grub_gcry_init_all (void)\n")
initfile.write ("{\n")
-for module in modules:
+for module in modules_sym_md:
initfile.write (" grub_%s_init ();\n" % module)
initfile.write ("}\n")
initfile.write ("\n")
initfile.write ("void\n")
initfile.write ("grub_gcry_fini_all (void)\n")
initfile.write ("{\n")
-for module in modules:
+for module in modules_sym_md:
initfile.write (" grub_%s_fini ();\n" % module)
initfile.write ("}\n")
initfile.close ()
diff --git a/util/import_gcrypth.sed b/util/import_gcrypth.sed
new file mode 100644
index 0000000..6cb53cf
--- /dev/null
+++ b/util/import_gcrypth.sed
@@ -0,0 +1,15 @@
+/^#@INSERT_SYS_SELECT_H@/ d
+/^@FALLBACK_SOCKLEN_T@/ d
+/^# *include <stdlib\.h>/ d
+/^# *include <string\.h>/ d
+/^# *include <winsock2\.h>/ d
+/^# *include <ws2tcpip\.h>/ d
+/^# *include <time\.h>/ d
+/^# *include <sys\/socket\.h>/ d
+/^# *include <sys\/time\.h>/ d
+/^# *include <gpg-error\.h>/ s,#include <gpg-error.h>,#include <grub/gcrypt/gpg-error.h>,
+/^typedef gpg_error_t gcry_error_t;/ d
+/^typedef gpg_err_code_t gcry_err_code_t;/ d
+/^typedef struct gcry_mpi \*gcry_mpi_t;/ d
+s,_gcry_mpi_invm,gcry_mpi_invm,g
+p \ No newline at end of file
diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in
index b3b88f0..2615cab 100644
--- a/util/powerpc/ieee1275/grub-mkrescue.in
+++ b/util/powerpc/ieee1275/grub-mkrescue.in
@@ -18,8 +18,6 @@ set -e
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
-transform="@program_transform_name@"
-
prefix="@prefix@"
exec_prefix="@exec_prefix@"
bindir="@bindir@"
@@ -36,7 +34,7 @@ fi
self=`basename $0`
-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`"
+grub_mkimage="${bindir}/@grub_mkimage@"
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR="@localedir@"
diff --git a/util/spkmodem-recv.c b/util/spkmodem-recv.c
new file mode 100644
index 0000000..9083c1a
--- /dev/null
+++ b/util/spkmodem-recv.c
@@ -0,0 +1,115 @@
+/* spkmodem-recv.c - decode spkmodem signals */
+/*
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * spkmodem-recv is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * spkmodem-recv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with spkmodem-recv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Compilation: gcc -o spkmodem-recv spkmodem-recv */
+/* Usage: parecord --channels=1 --rate=48000 --format=s16le | ./spkmodem-recv */
+
+#define SAMPLES_PER_TRAME 240
+#define FREQ_SEP_MIN 5
+#define FREQ_SEP_MAX 15
+#define FREQ_DATA_MIN 15
+#define FREQ_DATA_THRESHOLD 25
+#define FREQ_DATA_MAX 60
+#define THRESHOLD 500
+
+#define DEBUG 0
+#define FLUSH_TIMEOUT 1
+
+static signed short trame[2 * SAMPLES_PER_TRAME];
+static signed short pulse[2 * SAMPLES_PER_TRAME];
+static int ringpos = 0;
+static int pos, f1, f2;
+static int amplitude = 0;
+static int lp = 0;
+
+static void
+read_sample (void)
+{
+ amplitude -= abs (trame[ringpos]);
+ f1 -= pulse[ringpos];
+ f1 += pulse[(ringpos + SAMPLES_PER_TRAME) % (2 * SAMPLES_PER_TRAME)];
+ f2 -= pulse[(ringpos + SAMPLES_PER_TRAME) % (2 * SAMPLES_PER_TRAME)];
+ fread (trame + ringpos, 1, sizeof (trame[0]), stdin);
+ amplitude += abs (trame[ringpos]);
+
+ if (pos ? (trame[ringpos] < -THRESHOLD)
+ : (trame[ringpos] > +THRESHOLD))
+ {
+ pulse[ringpos] = 1;
+ pos = !pos;
+ f2++;
+ }
+ else
+ pulse[ringpos] = 0;
+ ringpos++;
+ ringpos %= 2 * SAMPLES_PER_TRAME;
+ lp++;
+}
+
+int
+main ()
+{
+ int bitn = 7;
+ char c = 0;
+ int i;
+ int llp = 0;
+ while (!feof (stdin))
+ {
+ if (lp > 3 * SAMPLES_PER_TRAME)
+ {
+ bitn = 7;
+ c = 0;
+ lp = 0;
+ llp++;
+ }
+ if (llp == FLUSH_TIMEOUT)
+ fflush (stdout);
+ if (f2 > FREQ_SEP_MIN && f2 < FREQ_SEP_MAX
+ && f1 > FREQ_DATA_MIN && f1 < FREQ_DATA_MAX)
+ {
+#if DEBUG
+ printf ("%d %d %d @%d\n", f1, f2, FREQ_DATA_THRESHOLD,
+ ftell (stdin) - sizeof (trame));
+#endif
+ if (f1 < FREQ_DATA_THRESHOLD)
+ c |= (1 << bitn);
+ bitn--;
+ if (bitn < 0)
+ {
+#if DEBUG
+ printf ("<%c, %x>", c, c);
+#else
+ printf ("%c", c);
+#endif
+ bitn = 7;
+ c = 0;
+ }
+ lp = 0;
+ llp = 0;
+ for (i = 0; i < SAMPLES_PER_TRAME; i++)
+ read_sample ();
+ continue;
+ }
+ read_sample ();
+ }
+ return 0;
+}