Compare commits

..

133 Commits

Author SHA1 Message Date
Vladimir Serbinenko
67a51e8e15 Include arrows and lines in ascii.h 2013-12-07 13:59:15 +01:00
Vladimir Serbinenko
5ff249072d * configure.ac: Make unifont mandatory on coreboot. 2013-12-07 11:47:19 +01:00
Vladimir Serbinenko
0277eab701 * configure.ac: Skip unifont 6.3 pcf and bdf. 2013-12-07 11:46:46 +01:00
Vladimir Serbinenko
4861b6c851 * Makefile.am: Remove partial font files if generation failed. 2013-12-07 11:39:35 +01:00
Andrey Borzenkov
3100cdc7f9 add grub_qsort_strcmp to use when sorting array of strings
Compare function used in qsort gets arguments by reference, so strcmp
cannot be used directly - it expects pointer to char, but gets pointer
to pointer to char.

Introduce new helper grub_qsort_strcmp and use it in grub-install.
This helper is going to be used in a couple more places as well so
add it to global file, not in grub-install.c.
2013-12-07 14:29:00 +04:00
Andrey Borzenkov
ad73cc3312 fix use of grub-probe instead of ${grub_probe} 2013-12-07 14:24:25 +04:00
Vladimir Serbinenko
4182262560 Don't add -mlong-calls when compiling with clang. 2013-12-06 11:58:17 +01:00
Vladimir Serbinenko
896f483d49 * configure.ac: Fix a typo. 2013-12-06 10:02:24 +01:00
Vladimir Serbinenko
8c534b85f1 Revamp relocation handling.
Move more code to common dl.c. Add missing veneers for arm and arm64.
	Decreases kernel size by 70 bytes on i386-pc (40-50 compressed)
2013-12-06 09:18:55 +01:00
Vladimir Serbinenko
a846dd4b3a * util/grub-mkimagexx.c: Fix reloc section generation for ia64. 2013-12-05 23:07:10 +01:00
Mike Gilbert
aa437b5890 gentpl.py: Use python3-style print function 2013-12-05 16:07:15 +00:00
Vladimir Serbinenko
b0f311f412 * util/grub-install.c: Mention Boot* variable. 2013-12-05 17:05:21 +01:00
Colin Watson
59b38922a1 Pacify compiler warning
* grub-core/osdep/linux/hostdisk.c
(grub_util_find_partition_start_os): Initialise start to avoid
spurious compiler warning.
2013-12-05 15:48:27 +00:00
Colin Watson
0480665b9d On Linux, read partition start offsets from sysfs if possible
This lets us cope with block device drivers that don't implement
HDIO_GETGEO.  Fixes Ubuntu bug #1237519.

* grub-core/osdep/linux/hostdisk.c (sysfs_partition_path): New
function.
(sysfs_partition_start): Likewise.
(grub_util_find_partition_start_os): Try sysfs_partition_start
before HDIO_GETGEO.
2013-12-05 13:51:52 +00:00
Leif Lindholm
bbeee1c4a3 grub-core/lib/fdt.c: correctly update size_dt_struct in add_subnode() 2013-12-05 11:44:41 +00:00
Vladimir Serbinenko
e5ed2f6947 Handle unaligned .bss on sparc64.
Current code improperly assumes that both __bss_start and _end are
	aligned to 8-bytes. Eliminating this assumption and explicitly align
	modules.
2013-12-05 06:35:19 +01:00
Vladimir Serbinenko
4a73746a04 * grub-core/boot/sparc64/ieee1275/boot.S [CDBOOT]: Move scratchpad
so it doesn't land in the middle of loaded image.
2013-12-04 19:54:37 +01:00
Vladimir Serbinenko
382b500ebe * configure.ac: Move all warning options that may be absent in
gcc >= 3.1 to optional.

	Note: while this allows to compile with older GCC, official requirements
	remain the same and no support for older GCC.
2013-12-04 14:53:25 +01:00
Colin Watson
3a82f8bb48 Fix grub-shell to avoid breaking "make distcheck"
Copying the themes directory in grub-shell isn't
parallel-test-friendly and breaks on the second test when the source
directory is read-only (as in "make distcheck").  Instead, add a
hidden --themes-directory option to grub-mkrescue et al, and use it
in grub-shell.
2013-12-04 13:36:34 +00:00
Vladimir Serbinenko
e3046431da * conf/Makefile.common (CFLAGS_GNULIB): Remove -Wno-old-style-definition
as it's no longer necessarry.
2013-12-04 14:32:04 +01:00
Vladimir Serbinenko
bdb6090d83 * configure.ac: Allow compilation with older GCC for ARM. 2013-12-04 12:42:09 +01:00
Vladimir Serbinenko
b73b70ebca * configure.ac: Add -no-integrated-as if {addme|ame} isn't supported.
* INSTALL: Note that GRUBwas successfully compiled with clang 3.2 for
	ppc.
2013-12-04 12:20:56 +01:00
Vladimir Serbinenko
8a3f0a24b5 * grub-core/kern/emu/main.c: Ignore missing prototype for main. 2013-12-04 10:28:23 +01:00
Vladimir Serbinenko
6f07c4e407 Pass font config to config.h and not by TARGET_CFLAGS as adding
arguments doesn't work if TARGET_CFLAGS is specified on command
	line.
2013-12-04 10:25:53 +01:00
Vladimir Serbinenko
60d5e9cbd9 * configure.ac: Add -Wvla if compiler supports it. 2013-12-04 10:08:57 +01:00
Vladimir Serbinenko
cd15c394cc * grub-core/osdep/windows/emuconsole.c (grub_console_putchar):
Remove variable length arrays.
	* grub-core/term/efi/console.c (grub_console_putchar): Likewise.
2013-12-04 10:05:33 +01:00
Vladimir Serbinenko
bb6e299ccb * grub-core/kern/i386/qemu/init.c: Remove variable length arrays. 2013-12-04 09:48:36 +01:00
Vladimir Serbinenko
85eb579ad9 * include/grub/types.h: Declare all byteswaps as inline functions
except compile-time ones.

	Solves variable shadowing in constructions like
	cpu_to_le (le_to_cpu(x) + 1).
2013-12-04 08:42:35 +01:00
Vladimir Serbinenko
47f88cc94e * grub-core/kern/efi/efi.c: Remove variable length arrays. 2013-12-04 08:39:22 +01:00
Vladimir Serbinenko
40b5739ff9 * grub-core/kern/uboot/init.c (uboot_timer_ms): Fix overflow after 71
minutes.
2013-12-04 08:26:39 +01:00
Vladimir Serbinenko
234d93464a * grub-core/disk/ieee1275/ofdisk.c: Remove variable length arrays.
* grub-core/net/drivers/ieee1275/ofnet.c: Likewise.
2013-12-04 08:10:01 +01:00
Colin Watson
0c0eab527f * grub-core/Makefile.core.def (setjmp): Distribute
lib/arm64/setjmp.S.
2013-12-03 18:11:18 +00:00
Colin Watson
44d4884779 Merge branch 'cjwatson/timeout-style' 2013-12-03 16:15:45 +00:00
Colin Watson
10955cda06 Credit and bug reference. 2013-12-03 16:14:01 +00:00
Colin Watson
f315b508ae Reduce nesting level. 2013-12-03 16:11:00 +00:00
Vladimir Serbinenko
9e4e6ddfbf * util/config.c: Add missing pointer adjustment.
Reported by: qwertial
2013-12-02 06:51:13 +01:00
Andrey Borzenkov
5037aa9a7b fix libgrub.pp build post arm64 merge
grub-core/kern/arm64/dl_helper.c:26:28: fatal error: grub/cpu/reloc.h: No such file or directory
2013-11-30 22:36:10 +04:00
Vladimir Serbinenko
8a952d20d1 Missing ChangeLog entry 2013-11-30 16:51:35 +01:00
Leif Lindholm
b29b77fee2 New port arm64-efi 2013-11-30 16:50:31 +01:00
Andrey Borzenkov
be0d45555e document sleep command exit codes 2013-11-30 14:57:11 +04:00
Vladimir Serbinenko
d74b9a1d1a Ensure that -mno-unaligned-access or some equivalent option is used. 2013-11-30 11:31:14 +01:00
Vladimir Serbinenko
35de6d4bac * grub-core/lib/libgcrypt/mpi/longlong.h: Fix compilation error with
-march=armv3.
2013-11-30 11:19:06 +01:00
Vladimir Serbinenko
ce55ed0389 Remove leftover GRUB_IA64_DL_TRAMP_SIZE. 2013-11-30 11:14:30 +01:00
Colin Watson
f70ab525f9 Remove a few references to GRUB_HIDDEN_TIMEOUT*
Reported by Andrey Borzenkov.
2013-11-29 17:19:37 +00:00
Colin Watson
9b70860ecc Consolidate timeout generation code a bit. 2013-11-29 16:11:53 +00:00
Colin Watson
095588ef34 Consistently ignore GRUB_TIMEOUT if GRUB_HIDDEN_TIMEOUT is set
Pointed out by Vladimir Serbinenko.
2013-11-29 15:30:44 +00:00
Colin Watson
2dbda2215c Fix documentation of behaviour after pressing ESC
Pointed out by Andrey Borzenkov.
2013-11-29 15:25:43 +00:00
Colin Watson
53cc63bf85 Add GRUB_TIMEOUT_STYLE_BUTTON support
Suggested by Vladimir Serbinenko.
2013-11-29 15:18:05 +00:00
Colin Watson
471b2683e7 Move deprecated grub-mkconfig options to a separate table
Suggested by Andrey Borzenkov.
2013-11-29 14:59:25 +00:00
Colin Watson
8ddf84bfb8 Fix "make -C docs dvi"
* docs/grub-dev.texi (Font Metrics): Exclude @image command from DVI
builds, since we don't have an EPS version of font_char_metrics.png.
Add leading dot to image extension per the Texinfo documentation.
2013-11-29 13:48:23 +00:00
Colin Watson
fd0df6d098 Fix build with FreeType 2.5.1
* util/grub-gen-asciih.c: Include FT_SYNTHESIS_H rather than
<freetype/ftsynth.h>, fixing build with FreeType 2.5.1.
* util/grub-gen-widthspec.c: Likewise.
* util/grub-mkfont.c: Likewise.
2013-11-29 12:19:36 +00:00
Andrey Borzenkov
69ca97c820 fix using grub device name as install device
Shell version of grub-install called grub-setup which resolved
install device name and called main setup routine. C version of
grub-install calls main setup routine directly, which leads
to the error:

grub2-install: info: grub-bios-setup  --verbose  --force  --skip-fs-probe --directory='/boot/grub2/i386-pc' --device-map='/boot/grub2/device.map' '(hd2)'.
grub2-install: info: reading /boot/grub2/i386-pc/boot.img.
grub2-install: info: reading /boot/grub2/i386-pc/core.img.
grub2-install: info: root is `(null)', dest is `(hd2)'.
grub2-install: info: Opening dest.
grub2-install: info: drive = -1.
grub2-install: error: disk `(hd2)' not found.

Move resolving of destination device name into main setup routine
so it is done consistently in both cases.
2013-11-29 11:32:34 +04:00
Vladimir Serbinenko
eec893ae49 * grub-core/kern/emu/hostfs.c (is_dir): Remove variable length arrays. 2013-11-29 05:52:20 +01:00
Vladimir Serbinenko
621e167fd6 * util/grub-fstest.c: Remove variable length arrays. 2013-11-29 05:50:32 +01:00
Vladimir Serbinenko
d54f647a4a * grub-core/osdep/linux/ofpath.c: Check return value of read. 2013-11-29 05:46:19 +01:00
Vladimir Serbinenko
c8a0f1b229 * util/mkimage.c (grub_install_generate_image): Use grub_crypto_hash for
computing crc32 rather than handling with md fundtions directly.
2013-11-29 04:14:26 +01:00
Vladimir Serbinenko
726409a513 * util/mkimage.c (grub_install_generate_image): Use grub_crypto_hash for
checking fwstart.img rather than md fundtions directly.
2013-11-29 04:05:44 +01:00
Vladimir Serbinenko
422e6e886c * util/grub-mkrescue.c (main): Check that fread succeeded. 2013-11-29 03:54:21 +01:00
Vladimir Serbinenko
af1faca3f8 * conf/Makefile.common: Remove -mexplicit-relocs and -DUSE_ASCII_FALLBACK on yeeloong.
-DUSE_ASCII_FALLBACK is already added by font snippets.
	-mexplicit-relocs isn't needed is compiler/assemblera are
	configured properly.
	If they're not we shouldn't attempt to fix it by ourselves.
	Binary compare between before and after shows no difference.
2013-11-29 03:45:50 +01:00
Vladimir Serbinenko
469021b4b3 Remove libgnulib.a and use its sources in dependencies directly.
This was the only instance of "library" in core config. A bug was
	reported that -fno-stack-protector wasn't passed to it. Instead of
	figuring out why it failed just remove this construction used
	needlessly.
2013-11-29 03:36:50 +01:00
Vladimir Serbinenko
83c256ba42 * grub-core/osdep/unix/password.c (grub_password_get): Check that
fgets succeeded.
2013-11-29 03:32:57 +01:00
Francesco Lavra
b67422d33d Fix command description in case of a device name passed as argument. 2013-11-28 17:25:52 +04:00
Colin Watson
827d87e9d6 Fix documentation of timeout expiry. 2013-11-28 11:01:53 +00:00
Colin Watson
8f236c1419 Revamp hidden timeout handling
Add a new timeout_style environment variable and a corresponding
GRUB_TIMEOUT_STYLE configuration key for grub-mkconfig.  This
controls hidden-timeout handling more simply than the previous
arrangements, and pressing any hotkeys associated with menu entries
during the hidden timeout will now boot the corresponding menu entry
immediately.

GRUB_HIDDEN_TIMEOUT=<non-empty> + GRUB_TIMEOUT=<non-zero> now
generates a warning, and if it shows the menu it will do so as if
the second timeout were not present.  Other combinations are
translated into reasonable equivalents.
2013-11-28 02:29:15 +00:00
Vladimir Serbinenko
2d76b4d81e Eliminate variable length arrays in grub_vsnprintf_real.
A bit tricky because this function has to continue to work without
	heap for short strings. Fixing prealloc to 32 arguments is reasonable
	but make all stack references use 32-bit offset rather than 8-bit one.
	So split va_args preparsing to separate function and put the prealloc
	into the caller.
2013-11-27 15:16:09 +01:00
Vladimir Serbinenko
4f9541226c Introduce grub_util_file_sync and use it instead of fsync(fileno(f)).
Fixes build for windows.
2013-11-27 14:13:50 +01:00
Vladimir Serbinenko
b1f742c103 * gentpl.py: Don't generate platform-dependent conditionals for
platform-independent targets.
2013-11-27 14:10:04 +01:00
Colin Watson
16ef26fd3a * grub-core/osdep/unix/exec.c (grub_util_exec_redirect): Remove
references to mdadm from otherwise generic code.
(grub_util_exec_pipe): Likewise.
(grub_util_exec_pipe_stderr): Likewise.
* grub-core/osdep/unix/getroot.c (grub_util_pull_lvm_by_command):
This function calls vgs, not mdadm; adjust variable names
accordingly.
2013-11-27 11:22:31 +00:00
Colin Watson
cf8c80ff77 Merge branch 'new-autogen' 2013-11-27 10:57:27 +00:00
Colin Watson
5c7206e45e Speed up test suite by avoiding fsync
Add grub_util_disable_fd_syncs call to turn grub_util_fd_sync calls into
no-ops, and use it in programs that copy files but do not need to take
special care to sync writes (grub-mknetdir, grub-rescue,
grub-mkstandalone).

On my laptop, this reduces partmap_test's runtime from 1236 seconds to
204 seconds.
2013-11-27 10:10:22 +00:00
Colin Watson
fc3f2b72cd * tests/util/grub-fs-tester.in: Execute xorriso from $PATH rather
than hardcoding /usr/local/bin/xorriso.
2013-11-26 23:51:48 +00:00
Colin Watson
34b2003def Handle #if/#endif and C-style comments in AutoGen definitions files. 2013-11-26 17:48:20 +00:00
Colin Watson
7e90f5ad25 Show file name in error messages from AutogenParser. 2013-11-26 17:42:56 +00:00
Colin Watson
ab4f15013a Generate Makefile.*.am directly from gentpl.py, eliminating the use of Autogen. The Autogen definitions files remain intact as they offer a useful abstraction. 2013-11-26 17:13:01 +00:00
Vladimir Serbinenko
1e4b358720 Add PCI command activation to all PCI drivers as required for coreboot
and maybe some other firmwares.
2013-11-26 14:21:11 +01:00
Vladimir Serbinenko
9208367d3f * grub-core/Makefile.am: Reduce gratuituous differences between Apple
and non-Apple variants of efiemu compile.
2013-11-26 11:38:12 +01:00
Andrey Borzenkov
67b9b7afd7 Add ChangeLog entry for previous commit 2013-11-25 23:14:04 +04:00
Andrey Borzenkov
c2b70d0981 Explicitly check for linking format to use for efiemu64 module
Similar to check for target linking format, also check for efiemu64
instead of hardcoding -melf_x86_64. This fixes compilation on *BSD
variants. We cannot easily reuse main target check because platforms
are different (main target is 32 bit and efiemu64 - 64 bit).

This commit adds EFIEMU64_LINK_FORMAT that contains detected
link option and is used in efiemu64.o linking instead of hardcoded
value.

Reported-By: Beeblebrox <zaphod@berentweb.com>
2013-11-25 22:32:55 +04:00
Vladimir Serbinenko
bee1b5ce3f * util/grub-mknetdir.c: Look for platform directories under pkglibdir
and not pkgdatadir.
2013-11-25 19:16:05 +01:00
Colin Watson
07e3b04742 Add a --locale-directory option to grub-install and related tools.
* include/grub/util/install.h (GRUB_INSTALL_OPTIONS): Add
--locale-directory option.
(enum grub_install_options): Add
GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY.
* util/grub-install-common.c (grub_install_help_filter): Handle
GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY.
(grub_install_parse): Likewise.
(get_localedir): New function to check for a user-provided option
before trying grub_util_get_localedir.
(copy_locales): Use get_localedir rather than
grub_util_get_localedir.  Handle differing locale directory layouts.
(grub_install_copy_files): Likewise.
2013-11-25 18:04:50 +00:00
Vladimir Serbinenko
ebd289335a Mention clang for arm64 2013-11-25 13:27:39 +01:00
Vladimir Serbinenko
d2f7902af0 Make arm64 compileable with clang 2013-11-25 13:06:56 +01:00
Vladimir Serbinenko
1005bed722 Use b.ge form for instructions 2013-11-25 13:04:44 +01:00
Vladimir Serbinenko
d6c92cdc34 Merge branch 'master' into leiflindholm/arm64
Conflicts:
	include/grub/util/install.h
2013-11-25 13:02:27 +01:00
Vladimir Serbinenko
61e1b9a49d * grub-core/osdep/unix/platform.c (get_ofpathname): Trim ending newline.
Don't rely on PATH_MAX.
2013-11-25 07:34:49 +01:00
Vladimir Serbinenko
c98dd165b0 * grub-core/genmoddep.awk: Use more portable && rather than and. 2013-11-25 07:32:51 +01:00
Vladimir Serbinenko
ff1c277ef8 * grub-core/kern/i386/pc/startup.S [__APPLE__]: Create _edata by placing
an object after data. While it doesn't seem right solution, it
	works well enough and OSX isn't main compilation platform.
2013-11-25 05:55:33 +01:00
Vladimir Serbinenko
c8f7614b98 * gentpl.py: Add -ed2016 in order to make objconv accept our binary.
While it doesn't seem right solution, it works well enough and
	OSX isn't main compilation platform.
2013-11-25 05:53:20 +01:00
Vladimir Serbinenko
246a434f61 * configure.ac: Add -static to LDFLAGS when using apple linker to
prevent it from pulling in dynamic linker.
2013-11-25 05:47:20 +01:00
Vladimir Serbinenko
5c066a81c2 Apple assembly doesn't handle symbol arithmetic well. So define an
offset symbol in boot.S and use it.
2013-11-24 07:12:12 +01:00
Vladimir Serbinenko
78f961efe9 Apple assembly doesn't handle symbol arithmetic well. So instead
of getting addres of kernel_sector + 4 define kernel_sector_high.
	It also makes code more readable.
2013-11-24 07:11:00 +01:00
Vladimir Serbinenko
09bc0a577d With Apple assembly in .macro environvemnt you have to use $$ instead
of $. So introduce new preprocessor macro MACRO_DOLLAR(x) which expands
	to $$x on Apple and to $x on everything else.
2013-11-24 07:08:18 +01:00
Vladimir Serbinenko
b700a427d2 * grub-core/Makefile.am: Use correct TARGET_OBJCONV rather than
OBJCONV.
2013-11-24 05:27:20 +01:00
Vladimir Serbinenko
4480b95dcd * grub-core/gdb/i386/machdep.S: Use xorl %eax, %eax on both Apple
and non-Apple. This instruction is shorter and faster,
	so no reason not to use it on both.
2013-11-24 05:17:24 +01:00
Vladimir Serbinenko
e77c81f6f8 * grub-core/lib/reed_solomon.c: Use section _text, _text rather than
.text when compiling for Apple.
2013-11-24 05:14:11 +01:00
Vladimir Serbinenko
971dbee521 * grub-core/term/arc/console.c: Add missing cast to silence warning. 2013-11-24 05:05:34 +01:00
Vladimir Serbinenko
6f2e82be3a * grub-core/boot/i386/pc/boot.S: Fix floppy probe. Due to missing
%dx restore the probe worked on non-existant drive. Reorganize the
	code a little bit to free 2 bytes necessary for push/pop.
2013-11-24 05:05:33 +01:00
Vladimir Serbinenko
9eec9699b9 * grub-core/kern/mips/arc/init.c (grub_machine_get_bootlocation):
Add missing cast to silence warning.
2013-11-23 15:35:01 +01:00
Keshav Padram Amburay
5ae5c54c7e * util/grub-install.c (update_nvram): Support --no-nvram flag
for EFI targets.
2013-11-23 13:02:12 +01:00
Vladimir Serbinenko
7b04fe6c9e * INSTALL: Add note about sparc64/ia64 with clang (unsupported). 2013-11-23 12:49:41 +01:00
Vladimir Serbinenko
e67566ce0a * util/garbage-gen.c: Add missing include of sys/time.h. 2013-11-23 12:42:30 +01:00
Vladimir Serbinenko
f93ddcfd1c Don't add -mflush-func if it's not supported by compiler. 2013-11-23 12:40:44 +01:00
Vladimir Serbinenko
1bba40f578 Move common BIOS/coreboot memory map declarations to
include/grub/i386/memory_raw.h and eliminate duplicate declarations.
2013-11-23 12:39:21 +01:00
Andrey Borzenkov
f65e14dc3a add util/garbage-gen.c to EXTRA_DIST 2013-11-23 14:39:35 +04:00
Vladimir Serbinenko
14a94bba6f * INSTALL: Document why older clang versions aren't appropriate. 2013-11-23 01:16:47 +01:00
Vladimir Serbinenko
8109c5d4e2 * INSTALL: Document about clang for mips. 2013-11-23 00:41:32 +01:00
Vladimir Serbinenko
a92b5cb8d8 * grub-core/lib/libgcrypt/mpi/longlong.h: Use C version with mips
clang.
2013-11-23 00:36:13 +01:00
Vladimir Serbinenko
4a23e2fe29 Add *-xen to the list of grub-install-common platforms. 2013-11-22 14:21:16 +01:00
Vladimir Serbinenko
a3ba74104e * configure.ac: Do not enforce -mcmodel=large. It's not necessarry with
3 last commits.
2013-11-22 13:07:51 +01:00
Vladimir Serbinenko
e1c22419ac * grub-core/kern/xen/init.c: Do not map more pages than we can address. 2013-11-22 13:04:29 +01:00
Vladimir Serbinenko
189090cee9 * grub-core/kern/efi/mm.c: Limit allocations to 2GiB when not compiling
with -mcmodel=large.
2013-11-22 13:03:19 +01:00
Vladimir Serbinenko
1a5b7b404f * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Add
range-checking for 32-bit quantities.
2013-11-22 13:01:14 +01:00
Vladimir Serbinenko
9cf12b20af * configure.ac: Compile with -fPIC when compiling with clang on
mips.
2013-11-22 12:50:41 +01:00
Vladimir Serbinenko
63a45330cb * configure.ac: Add -no-integrated-as on mips(el) to TARGET_CCASFLAGS
when compiling with clang.
2013-11-22 12:48:32 +01:00
Vladimir Serbinenko
4a0aaad022 clang emits calls to abort () under some unknown conditions.
Export abort () when compiling with clang.
2013-11-22 12:42:58 +01:00
Vladimir Serbinenko
095bb1bfa5 * docs/grub-dev.texi: Document stack and heap sizes. 2013-11-22 12:03:44 +01:00
Vladimir Serbinenko
3937bd962b * include/grub/i386/pc/memory.h: Decrease
GRUB_MEMORY_MACHINE_SCRATCH_SIZE and increase
	GRUB_MEMORY_MACHINE_PROT_STACK_SIZE.
	The binary doesn't change (checked). It's more to better reflect actual
	usage.
2013-11-22 12:02:00 +01:00
Vladimir Serbinenko
ddb3efc906 * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_open): Ensure
at compile time that enough of scratch size is available.
2013-11-22 12:00:10 +01:00
Vladimir Serbinenko
4e42521d8c * grub-core/kern/x86_64/efi/callwrap.S: Fix stack alignment.
Previously we misaligned stack by 8 in startup.S and compensated
	for it in callwrap.S. According to ABI docs (EFI and sysv amd64)
	right behaviour is to align stack in startup.S and keep it aligned
	in callwrap.S. startup.S part was committed few commits before. This
	takes care of callwrap.S.
	Reported by: Gary Lin.
2013-11-22 05:40:32 +01:00
Vladimir Serbinenko
054efe541f * grub-core/boot/mips/startup_raw.S: Handle the case of gap between
.data and .bss. May happen if compiler and assembly use different
	alignment.
2013-11-22 05:07:32 +01:00
Vladimir Serbinenko
a0e1befb57 On MIPS handle got16 relocations to local symbols in an ABI-compliant
way.
2013-11-22 05:03:17 +01:00
Vladimir Serbinenko
c36c73f681 Add support for a new magic symbol _gp_disp on mips to handle PIC
binaries.
2013-11-22 04:56:10 +01:00
Vladimir Serbinenko
6f4a19f59f Use $t9 for indirect calls from asm to C as PIC ABI requires. 2013-11-22 04:45:05 +01:00
Vladimir Serbinenko
0d8f04cd83 Remove -march=mips3 from TARGET_CCASFLAGS as it creates linking problem
when rest of GRUB is compiled for hisher stepping. Instead use
	.set mips3/.set mips1 around cache and sync opcodes.
2013-11-22 04:36:53 +01:00
Vladimir Serbinenko
4906052019 Unify GOT/trampoline handling between PPC, MIPS and IA64 as they
do essentially the same thing, do it in similar way.
2013-11-21 21:54:33 +01:00
Colin Watson
c6a823e267 * util/grub-mkrescue.c (main): If a source directory is not
specified, read platform-specific files from subdirectories of
pkglibdir, not pkgdatadir.
2013-11-21 17:36:45 +00:00
Colin Watson
b7f9aedfac * grub-core/normal/progress.c: Remove unused file. 2013-11-21 15:37:57 +00:00
Vladimir Serbinenko
7dd0a30361 * grub-core/lib/crypto.c (grub_crypto_hash): Remove variable length
array.
2013-11-20 20:09:18 +01:00
Vladimir Serbinenko
ca120e31f2 * util/grub-mkconfig.in: Say explicit "grub configuration" rather
than grub.cfg.
2013-11-20 10:18:19 +01:00
Leif Lindholm
8a07b55a04 arm64: cache maintenance code rework + bugfix 2013-11-19 10:05:23 +00:00
Vladimir Serbinenko
d3def58c52 Add missing arm64 declaration 2013-11-18 17:52:57 +01:00
Vladimir Serbinenko
96fa2d9d02 Merge branch 'master' into leiflindholm/arm64 2013-11-18 17:51:28 +01:00
Leif Lindholm
15a463d742 ARM 64 port by Leif Lindholm 2013-11-16 20:52:55 +01:00
195 changed files with 4983 additions and 2856 deletions

1
.gitignore vendored
View File

@@ -159,7 +159,6 @@ GPATH
GRTAGS
GSYMS
GTAGS
Makefile.tpl
compile
depcomp
mdate-sh

611
ChangeLog
View File

@@ -1,3 +1,614 @@
2013-12-07 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Make unifont mandatory on coreboot.
2013-12-07 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Skip unifont 6.3 pcf and bdf.
2013-12-07 Vladimir Serbinenko <phcoder@gmail.com>
* Makefile.am: Remove partial font files if generation failed.
2013-12-07 Andrey Borzenkov <arvidjaar@gmail.com>
* util/misc.c (grub_qsort_strcmp): Add qsort helper function to sort
strings.
* include/grub/util/misc.h: Define it ...
* util/grub-install.c (device_map_check_duplicates): ... and use it.
2013-12-07 Andrey Borzenkov <arvidjaar@gmail.com>
* util/grub.d/30_os-prober.in: Fix use of grub-probe instead of
${grub_probe}.
2013-12-06 Vladimir Serbinenko <phcoder@gmail.com>
Don't add -mlong-calls when compiling with clang.
2013-12-06 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Fix a typo.
2013-12-06 Vladimir Serbinenko <phcoder@gmail.com>
Revamp relocation handling.
Move more code to common dl.c. Add missing veneers for arm and arm64.
Decreases kernel size by 70 bytes on i386-pc (40-50 compressed)
2013-12-05 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mkimagexx.c: Fix reloc section generation for ia64.
2013-12-05 Mike Gilbert <floppym@gentoo.org>
* INSTALL: Raise minimum python version to 2.6.
* gentpl.py: Use python3-style print function.
2013-12-05 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-install.c: Mention Boot* variable.
2013-12-05 Colin Watson <cjwatson@ubuntu.com>
* grub-core/osdep/linux/hostdisk.c
(grub_util_find_partition_start_os): Initialise start to avoid
spurious compiler warning.
2013-12-05 Colin Watson <cjwatson@ubuntu.com>
On Linux, read partition start offsets from sysfs if possible, to
cope with block device drivers that don't implement HDIO_GETGEO.
Fixes Ubuntu bug #1237519.
* grub-core/osdep/linux/hostdisk.c (sysfs_partition_path): New
function.
(sysfs_partition_start): Likewise.
(grub_util_find_partition_start_os): Try sysfs_partition_start
before HDIO_GETGEO.
2013-12-05 Leif Lindholm <leif.lindholm@linaro.org>
* grub-core/kern/fdt.c: Update struct size when adding node.
2013-12-05 Vladimir Serbinenko <phcoder@gmail.com>
Handle unaligned .bss on sparc64.
Current code improperly assumes that both __bss_start and _end are
aligned to 8-bytes. Eliminating this assumption and explicitly align
modules.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/boot/sparc64/ieee1275/boot.S [CDBOOT]: Move scratchpad
so it doesn't land in the middle of loaded image.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Move all warning options that may be absent in
gcc >= 3.1 to optional.
Note: while this allows to compile with older GCC, official requirements
remain the same and no support for older GCC.
2013-12-04 Colin Watson <cjwatson@ubuntu.com>
Copying the themes directory in grub-shell isn't
parallel-test-friendly and breaks on the second test when the source
directory is read-only (as in "make distcheck"). Instead, add a
hidden --themes-directory option to grub-mkrescue et al, and use it
in grub-shell.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* conf/Makefile.common (CFLAGS_GNULIB): Remove -Wno-old-style-definition
as it's no longer necessarry.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Allow compilation with older GCC for ARM.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Add -no-integrated-as if {addme|ame} isn't supported.
* INSTALL: Note that GRUBwas successfully compiled with clang 3.2 for
ppc.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/emu/main.c: Ignore missing prototype for main.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
Pass font config to config.h and not by TARGET_CFLAGS as adding
arguments doesn't work if TARGET_CFLAGS is specified on command
line.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Add -Wvla if compiler supports it.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/osdep/windows/emuconsole.c (grub_console_putchar):
Remove variable length arrays.
* grub-core/term/efi/console.c (grub_console_putchar): Likewise.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/i386/qemu/init.c: Remove variable length arrays.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* include/grub/types.h: Declare all byteswaps as inline functions
except compile-time ones.
Solves variable shadowing in constructions like
cpu_to_le (le_to_cpu(x) + 1).
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/efi/efi.c: Remove variable length arrays.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/uboot/init.c (uboot_timer_ms): Fix overflow after 71
minutes.
2013-12-04 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/disk/ieee1275/ofdisk.c: Remove variable length arrays.
* grub-core/net/drivers/ieee1275/ofnet.c: Likewise.
2013-12-03 Colin Watson <cjwatson@ubuntu.com>
* grub-core/Makefile.core.def (setjmp): Distribute
lib/arm64/setjmp.S.
2013-12-03 Colin Watson <cjwatson@ubuntu.com>
Add a new timeout_style environment variable and a corresponding
GRUB_TIMEOUT_STYLE configuration key for grub-mkconfig. This
controls hidden-timeout handling more simply than the previous
arrangements, and pressing any hotkeys associated with menu entries
during the hidden timeout will now boot the corresponding menu entry
immediately.
GRUB_HIDDEN_TIMEOUT=<non-empty> + GRUB_TIMEOUT=<non-zero> now
generates a warning, and if it shows the menu it will do so as if
the second timeout were not present. Other combinations are
translated into reasonable equivalents.
Based loosely on work by Franz Hsieh. Fixes Ubuntu bug #1178618.
2013-12-02 Vladimir Serbinenko <phcoder@gmail.com>
* util/config.c: Add missing pointer adjustment.
Reported by: qwertial
2013-11-30 Andrey Borzenkov <arvidjaar@gmail.com>
* grub-core/kern/arm64/dl_helper.c: Include grub/arm64/reloc.h
directly, not via `cpu' link, to fix libgrub.pp generation.
2013-11-30 Leif Lindholm <leif.lindholm@linaro.org>
New port arm64-efi.
2013-11-30 Andrey Borzenkov <arvidjaar@gmail.com>
* docs/grub.texi (sleep): Document exit codes.
2013-11-30 Vladimir Serbinenko <phcoder@gmail.com>
Ensure that -mno-unaligned-access or some equivalent option is used.
2013-11-30 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/lib/libgcrypt/mpi/longlong.h: Fix compilation error with
-march=armv3.
2013-11-30 Vladimir Serbinenko <phcoder@gmail.com>
Remove leftover GRUB_IA64_DL_TRAMP_SIZE.
2013-11-29 Colin Watson <cjwatson@ubuntu.com>
* docs/grub-dev.texi (Font Metrics): Exclude @image command from DVI
builds, since we don't have an EPS version of font_char_metrics.png.
Add leading dot to image extension per the Texinfo documentation.
2013-11-29 Colin Watson <cjwatson@ubuntu.com>
* util/grub-gen-asciih.c: Include FT_SYNTHESIS_H rather than
<freetype/ftsynth.h>, fixing build with FreeType 2.5.1.
* util/grub-gen-widthspec.c: Likewise.
* util/grub-mkfont.c: Likewise.
2013-11-29 Andrey Borzenkov <arvidjaar@gmail.com>
* util/grub-setup.c (main): Move parsing of (hdX) syntax to ...
* util/setup.c (SETUP): ... here. Fixes regression: grub-install
failed to install on (hdX).
* util/grub-setup.c (get_device_name): Remove, not needed after
above change.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/emu/hostfs.c (is_dir): Remove variable length arrays.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-fstest.c: Remove variable length arrays.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/osdep/linux/ofpath.c: Check return value of read.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* util/mkimage.c (grub_install_generate_image): Use grub_crypto_hash for
computing crc32 rather than handling with md fundtions directly.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* util/mkimage.c (grub_install_generate_image): Use grub_crypto_hash for
checking fwstart.img rather than md fundtions directly.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mkrescue.c (main): Check that fread succeeded.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* conf/Makefile.common: Remove -mexplicit-relocs and
-DUSE_ASCII_FALLBACK on yeeloong.
-DUSE_ASCII_FALLBACK is already added by font snippets.
-mexplicit-relocs isn't needed is compiler/assemblera are
configured properly.
If they're not we shouldn't attempt to fix it by ourselves.
Binary compare between before and after shows no difference.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/Makefile.core.def: Remove libgnulib.a and use its
sources in dependencies directly.
This was the only instance of "library" in core config. A bug was
reported that -fno-stack-protector wasn't passed to it. Instead of
figuring out why it failed just remove this construction used
needlessly.
2013-11-29 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/osdep/unix/password.c (grub_password_get): Check that
fgets succeeded.
2013-11-27 Francesco Lavra <francescolavra.fl@gmail.com>
* docs/grub.texi (ls): Fix command description in case of a device name
passed as argument.
2013-11-27 Vladimir Serbinenko <phcoder@gmail.com>
Eliminate variable length arrays in grub_vsnprintf_real.
A bit tricky because this function has to continue to work without
heap for short strings. Fixing prealloc to 32 arguments is reasonable
but make all stack references use 32-bit offset rather than 8-bit one.
So split va_args preparsing to separate function and put the prealloc
into the caller.
2013-11-27 Vladimir Serbinenko <phcoder@gmail.com>
Introduce grub_util_file_sync and use it instead of fsync(fileno(f)).
Fixes build for windows.
2013-11-27 Vladimir Serbinenko <phcoder@gmail.com>
* gentpl.py: Don't generate platform-dependent conditionals for
platform-independent targets.
2013-11-27 Colin Watson <cjwatson@ubuntu.com>
* grub-core/osdep/unix/exec.c (grub_util_exec_redirect): Remove
references to mdadm from otherwise generic code.
(grub_util_exec_pipe): Likewise.
(grub_util_exec_pipe_stderr): Likewise.
* grub-core/osdep/unix/getroot.c (grub_util_pull_lvm_by_command):
This function calls vgs, not mdadm; adjust variable names
accordingly.
2013-11-27 Colin Watson <cjwatson@ubuntu.com>
Generate Makefile.*.am directly from gentpl.py, eliminating the use
of Autogen. The Autogen definitions files remain intact as they
offer a useful abstraction.
2013-11-27 Colin Watson <cjwatson@ubuntu.com>
Add grub_util_disable_fd_syncs call to turn grub_util_fd_sync calls
into no-ops, and use it in programs that copy files but do not need
to take special care to sync writes (grub-mknetdir, grub-rescue,
grub-mkstandalone).
2013-11-26 Colin Watson <cjwatson@ubuntu.com>
* tests/util/grub-fs-tester.in: Execute xorriso from $PATH rather
than hardcoding /usr/local/bin/xorriso.
2013-11-26 Vladimir Serbinenko <phcoder@gmail.com>
Add PCI command activation to all PCI drivers as required for coreboot
and maybe some other firmwares.
2013-11-26 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/Makefile.am: Reduce gratuituous differences between Apple
and non-Apple variants of efiemu compile.
2013-11-25 Andrey Borzenkov <arvidjaar@gmail.com>
* configure.ac: Add explicit check for linking format of
efiemu64; save it as EFIEMU64_LINK_FORMAT.
* grub-core/Makefile.am: Use EFIEMU64_LINK_FORMAT instead of
hardcoding linking format.
2013-11-25 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mknetdir.c: Look for platform directories under pkglibdir
and not pkgdatadir.
2013-11-25 Colin Watson <cjwatson@ubuntu.com>
2013-11-25 Vladimir Serbinenko <phcoder@gmail.com>
Add a --locale-directory option to grub-install and related tools.
* include/grub/util/install.h (GRUB_INSTALL_OPTIONS): Add
--locale-directory option.
(enum grub_install_options): Add
GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY.
* util/grub-install-common.c (grub_install_help_filter): Handle
GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY.
(grub_install_parse): Likewise.
(get_localedir): New function to check for a user-provided option
before trying grub_util_get_localedir.
(copy_locales): Use get_localedir rather than
grub_util_get_localedir. Handle differing locale directory layouts.
(grub_install_copy_files): Likewise.
2013-11-25 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/osdep/unix/platform.c (get_ofpathname): Trim ending newline.
Don't rely on PATH_MAX.
2013-11-25 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/genmoddep.awk: Use more portable && rather than and.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/i386/pc/startup.S [__APPLE__]: Create _edata by placing
an object after data. While it doesn't seem right solution, it
works well enough and OSX isn't main compilation platform.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
* gentpl.py: Add -ed2016 in order to make objconv accept our binary.
While it doesn't seem right solution, it works well enough and
OSX isn't main compilation platform.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Add -static to LDFLAGS when using apple linker to
prevent it from pulling in dynamic linker.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
Apple assembly doesn't handle symbol arithmetic well. So define an
offset symbol in boot.S and use it.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
Apple assembly doesn't handle symbol arithmetic well. So instead
of getting addres of kernel_sector + 4 define kernel_sector_high.
It also makes code more readable.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
With Apple assembly in .macro environvemnt you have to use $$ instead
of $. So introduce new preprocessor macro MACRO_DOLLAR(x) which expands
to $$x on Apple and to $x on everything else.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/Makefile.am: Use correct TARGET_OBJCONV rather than
OBJCONV.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/gdb/i386/machdep.S: Use xorl %eax, %eax on both Apple
and non-Apple. This instruction is shorter and faster,
so no reason not to use it on both.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/lib/reed_solomon.c: Use section _text, _text rather than
.text when compiling for Apple.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/term/arc/console.c: Add missing cast to silence warning.
2013-11-24 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/boot/i386/pc/boot.S: Fix floppy probe. Due to missing
%dx restore the probe worked on non-existant drive. Reorganize the
code a little bit to free 2 bytes necessary for push/pop.
2013-11-23 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/mips/arc/init.c (grub_machine_get_bootlocation):
Add missing cast to silence warning.
2013-11-23 Keshav Padram Amburay <the.ridikulus.rat@gmail.com>
* util/grub-install.c (update_nvram): Support --no-nvram flag
for EFI targets.
2013-11-23 Vladimir Serbinenko <phcoder@gmail.com>
* INSTALL: Add note about sparc64/ia64 with clang (unsupported).
2013-11-23 Vladimir Serbinenko <phcoder@gmail.com>
* util/garbage-gen.c: Add missing include of sys/time.h.
2013-11-23 Vladimir Serbinenko <phcoder@gmail.com>
Don't add -mflush-func if it's not supported by compiler.
2013-11-23 Vladimir Serbinenko <phcoder@gmail.com>
Move common BIOS/coreboot memory map declarations to
include/grub/i386/memory_raw.h and eliminate duplicate declarations.
2013-11-22 Andrey Borzenkov <arvidjaar@gmail.com>
* Makefile.am: Add util/garbage-gen.c to EXTRA_DIST.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* INSTALL: Document why older clang versions aren't appropriate.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* INSTALL: Document about clang for mips.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/lib/libgcrypt/mpi/longlong.h: Use C version with mips
clang.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
Add *-xen to the list of grub-install-common platforms.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Do not enforce -mcmodel=large. It's not necessarry with
3 last commits.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/xen/init.c: Do not map more pages than we can address.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/efi/mm.c: Limit allocations to 2GiB when not compiling
with -mcmodel=large.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Add
range-checking for 32-bit quantities.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Compile with -fPIC when compiling with clang on
mips.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Add -no-integrated-as on mips(el) to TARGET_CCASFLAGS
when compiling with clang.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
clang emits calls to abort () under some unknown conditions.
Export abort () when compiling with clang.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* docs/grub-dev.texi: Document stack and heap sizes.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* include/grub/i386/pc/memory.h: Decrease
GRUB_MEMORY_MACHINE_SCRATCH_SIZE and increase
GRUB_MEMORY_MACHINE_PROT_STACK_SIZE.
The binary doesn't change (checked). It's more to better reflect actual
usage.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_open): Ensure
at compile time that enough of scratch size is available.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/kern/x86_64/efi/callwrap.S: Fix stack alignment.
Previously we misaligned stack by 8 in startup.S and compensated
for it in callwrap.S. According to ABI docs (EFI and sysv amd64)
right behaviour is to align stack in startup.S and keep it aligned
in callwrap.S. startup.S part was committed few commits before. This
takes care of callwrap.S.
Reported by: Gary Lin.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/boot/mips/startup_raw.S: Handle the case of gap between
.data and .bss. May happen if compiler and assembly use different
alignment.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
On MIPS handle got16 relocations to local symbols in an ABI-compliant
way.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
Add support for a new magic symbol _gp_disp on mips to handle PIC
binaries.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
Use $t9 for indirect calls from asm to C as PIC ABI requires.
2013-11-22 Vladimir Serbinenko <phcoder@gmail.com>
Remove -march=mips3 from TARGET_CCASFLAGS as it creates linking problem
when rest of GRUB is compiled for hisher stepping. Instead use
.set mips3/.set mips1 around cache and sync opcodes.
2013-11-21 Vladimir Serbinenko <phcoder@gmail.com>
Unify GOT/trampoline handling between PPC, MIPS and IA64 as they
do essentially the same thing, do it in similar way.
2013-11-21 Colin Watson <cjwatson@ubuntu.com>
* util/grub-mkrescue.c (main): If a source directory is not
specified, read platform-specific files from subdirectories of
pkglibdir, not pkgdatadir.
2013-11-21 Colin Watson <cjwatson@ubuntu.com>
* grub-core/normal/progress.c: Remove unused file.
2013-11-20 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/lib/crypto.c (grub_crypto_hash): Remove variable length
array.
2013-11-20 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mkconfig.in: Say explicit "grub configuration" rather
than grub.cfg.
2013-11-20 Vladimir Serbinenko <phcoder@gmail.com>
* coreboot.cfg: Add missing file.

17
INSTALL
View File

@@ -15,8 +15,20 @@ configuring the GRUB.
Note: older versions may work but support is limited
Note: clang 3.2 or later works for i386 and x86_64 targets but results in
much bigger binaries.
earlier versions not tested
Note: clang 3.2 or later works for arm
Note: clang 3.4 or later works for powerpc
earlier versions not tested
Note: clang 3.3 or later works for arm64
earlier versions have no arm64 support
Note: clang 3.3 or later works for mips(el)
earlier versions fail to generate .reginfo and hence gprel relocations
fail.
Note: clang 3.2 or later works for powerpc
earlier versions not tested
Note: clang has no support for generating 64-bit sparc code and hence you
can't compile GRUB for sparc64 with clang
Note: clang has no support for ia64 and hence you can't compile GRUB
for ia64 with clang
* GNU Make
* GNU Bison 2.3 or later
* GNU gettext 0.17 or later
@@ -42,10 +54,9 @@ To build GRUB's graphical terminal (gfxterm), you need:
If you use a development snapshot or want to hack on GRUB you may
need the following.
* Python 2.5.2 or later
* Python 2.6 or later
* Autoconf 2.60 or later
* Automake 1.10.1 or later
* Autogen 5.10 or later
Prerequisites for make-check:

View File

@@ -73,6 +73,7 @@ CLEANFILES += build-grub-mkfont
garbage-gen: util/garbage-gen.c
$(BUILD_CC) -o $@ $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $^
CLEANFILES += garbage-gen
EXTRA_DIST += util/garbage-gen.c
build-grub-gen-asciih: util/grub-gen-asciih.c
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) -Wall -Werror
@@ -102,7 +103,7 @@ EXTRA_DIST += $(starfield_theme_files)
EXTRA_DIST += $(srcdir)/themes/starfield/src/slider_s.xcf $(srcdir)/themes/starfield/src/slider_n.xcf $(srcdir)/themes/starfield/src/slider_c.xcf $(srcdir)/themes/starfield/src/blob_nw.xcf $(srcdir)/themes/starfield/src/bootmenu/center.xcf $(srcdir)/themes/starfield/src/bootmenu/corner.xcf $(srcdir)/themes/starfield/src/bootmenu/side.xcf $(srcdir)/themes/starfield/src/terminalbox/side.xcf $(srcdir)/themes/starfield/src/terminalbox/corner.xcf $(srcdir)/themes/starfield/src/terminalbox/center.xcf
unicode.pf2: $(FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -o $@ $(FONT_SOURCE)
./build-grub-mkfont -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1)
CLEANFILES += unicode.pf2
# Arrows and lines are needed to draw the menu, so always include them
@@ -110,19 +111,19 @@ UNICODE_ARROWS=0x2190-0x2193
UNICODE_LINES=0x2501-0x251B
ascii.pf2: $(FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES)
./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
CLEANFILES += ascii.pf2
euro.pf2: $(FONT_SOURCE) build-grub-mkfont
./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES)
./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
CLEANFILES += euro.pf2
ascii.h: $(FONT_SOURCE) build-grub-gen-asciih
./build-grub-gen-asciih $(FONT_SOURCE) $@
./build-grub-gen-asciih $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
CLEANFILES += ascii.h
widthspec.h: $(FONT_SOURCE) build-grub-gen-widthspec
./build-grub-gen-widthspec $(FONT_SOURCE) $@
./build-grub-gen-widthspec $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
CLEANFILES += widthspec.h
# Install config.h into platformdir

View File

@@ -156,6 +156,8 @@ library = {
common = grub-core/io/gzio.c;
common = grub-core/io/lzopio.c;
common = grub-core/kern/ia64/dl_helper.c;
common = grub-core/kern/arm/dl_helper.c;
common = grub-core/kern/arm64/dl_helper.c;
common = grub-core/lib/minilzo/minilzo.c;
common = grub-core/lib/xzembed/xz_dec_bcj.c;
common = grub-core/lib/xzembed/xz_dec_lzma2.c;
@@ -177,8 +179,6 @@ program = {
extra_dist = grub-core/osdep/unix/config.c;
common = util/config.c;
common = grub-core/kern/arm/dl_helper.c;
extra_dist = util/grub-mkimagexx.c;
ldadd = libgrubmods.a;
@@ -512,8 +512,6 @@ program = {
common = grub-core/kern/emu/hostfs.c;
common = grub-core/disk/host.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c;
@@ -558,8 +556,6 @@ program = {
common = grub-core/kern/emu/hostfs.c;
common = grub-core/disk/host.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c;
@@ -595,8 +591,6 @@ program = {
common = grub-core/osdep/config.c;
common = util/config.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c;
enable = noemu;
common = grub-core/kern/emu/argp_common.c;
@@ -632,8 +626,6 @@ program = {
common = grub-core/osdep/config.c;
common = util/config.c;
common = grub-core/kern/arm/dl_helper.c;
common = util/resolve.c;
common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c;

View File

@@ -474,23 +474,3 @@ dnl program.
AC_DEFUN([grub_TRANSFORM],[dnl
AC_SUBST(AS_TR_SH([$1]), [`AS_ECHO([$1]) | sed "$program_transform_name"`])dnl
])
dnl Check if the C compiler supports `-mno-unaligned-access'.
AC_DEFUN([grub_CHECK_NO_UNALIGNED_ACCESS],[
[# foobar
nua_possible=yes]
AC_MSG_CHECKING([whether `$CC' supports `-mno-unaligned-access'])
AC_LANG_CONFTEST([AC_LANG_SOURCE([[
int main() {
return 0;
}
]])])
[if eval "$ac_compile -S -mno-unaligned-access -o conftest.s" 2> /dev/null; then]
AC_MSG_RESULT([yes])
[rm -f conftest.s
else
nua_possible=no]
AC_MSG_RESULT([no])
[fi]
])

View File

@@ -8,8 +8,6 @@ unset LC_ALL
find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' |sort > po/POTFILES.in
find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in
autogen --version >/dev/null || exit 1
echo "Importing unicode..."
python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt grub-core/unidata.c
@@ -32,10 +30,7 @@ for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul
ln -s generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x"
done
echo "Creating Makefile.tpl..."
python gentpl.py | sed -e '/^$/{N;/^\n$/D;}' > Makefile.tpl
echo "Running autogen..."
echo "Generating Automake input..."
# Automake doesn't like including files from a path outside the project.
rm -f contrib grub-core/contrib
@@ -59,8 +54,8 @@ for extra in contrib/*/Makefile.core.def; do
fi
done
cat $UTIL_DEFS | autogen -T Makefile.tpl | sed -e '/^$/{N;/^\n$/D;}' > Makefile.util.am
cat $CORE_DEFS | autogen -T Makefile.tpl | sed -e '/^$/{N;/^\n$/D;}' > grub-core/Makefile.core.am
python gentpl.py $UTIL_DEFS > Makefile.util.am
python gentpl.py $CORE_DEFS > grub-core/Makefile.core.am
for extra in contrib/*/Makefile.common; do
if test -e "$extra"; then

View File

@@ -6,23 +6,18 @@ export LC_COLLATE := C
unexport LC_ALL
# Platform specific options
if COND_mips_loongson
CFLAGS_PLATFORM += -mexplicit-relocs
CPPFLAGS_PLATFORM = -DUSE_ASCII_FALLBACK
endif
if COND_mips
CFLAGS_PLATFORM += -mflush-func=grub_red_herring
CCASFLAGS_PLATFORM = -march=mips3
endif
if COND_sparc64_ieee1275
CFLAGS_PLATFORM += -mno-app-regs
LDFLAGS_PLATFORM = -Wl,-melf64_sparc -mno-relax
endif
if COND_arm
CFLAGS_PLATFORM += -mthumb-interwork -mlong-calls
CFLAGS_PLATFORM += -mthumb-interwork
CCASFLAGS_PLATFORM = -mthumb-interwork
LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache
endif
if COND_arm64
CFLAGS_PLATFORM += -mcmodel=large
endif
#FIXME: discover and check XEN headers
CPPFLAGS_XEN = -I/usr/include
@@ -78,7 +73,7 @@ grubconfdir = $(sysconfdir)/grub.d
platformdir = $(pkglibdir)/$(target_cpu)-$(platform)
starfielddir = $(pkgdatadir)/themes/starfield
CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition
CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib
CFLAGS_POSIX = -fno-builtin
@@ -135,20 +130,15 @@ EXTRA_DIST =
CLEANFILES =
BUILT_SOURCES =
# Rules for autogen definition files
.PRECIOUS: $(top_srcdir)/Makefile.tpl
$(top_srcdir)/Makefile.tpl: $(top_srcdir)/gentpl.py
python $< | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1)
mv $@.new $@
# Rules for Automake input
.PRECIOUS: $(top_srcdir)/Makefile.util.am
$(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)
$(top_srcdir)/Makefile.util.am: $(top_srcdir)/gentpl.py $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def
python $^ > $@.new || (rm -f $@.new; exit 1)
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
$(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/gentpl.py $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def
if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./autogen.sh manually." >&2; exit 1; fi
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)
python $^ > $@.new || (rm -f $@.new; exit 1)
mv $@.new $@

View File

@@ -2,7 +2,6 @@ EXTRA_DIST += autogen.sh
EXTRA_DIST += geninit.sh
EXTRA_DIST += gentpl.py
EXTRA_DIST += Makefile.tpl
EXTRA_DIST += Makefile.util.def
EXTRA_DIST += Makefile.utilgcry.def

View File

@@ -28,6 +28,7 @@
#elif defined (GRUB_UTIL) || !defined (GRUB_MACHINE)
#include <config-util.h>
#else
#define HAVE_FONT_SOURCE @HAVE_FONT_SOURCE@
/* Define if C symbols get an underscore after compilation. */
#define HAVE_ASM_USCORE @HAVE_ASM_USCORE@
/* Define it to \"addr32\" or \"addr32;\" to make GAS happy. */

View File

@@ -99,6 +99,9 @@ case "$target_cpu" in
arm*)
target_cpu=arm;
;;
aarch64*)
target_cpu=arm64;
;;
esac
# Specify the platform (such as firmware).
@@ -120,6 +123,7 @@ if test "x$with_platform" = x; then
mips-*) platform=arc ;;
ia64-*) platform=efi ;;
arm-*) platform=uboot ;;
arm64-*) platform=efi ;;
*) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
esac
else
@@ -160,6 +164,7 @@ case "$target_cpu"-"$platform" in
mipsel-loongson) ;;
arm-uboot) ;;
arm-efi) ;;
arm64-efi) ;;
*-emu) ;;
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
esac
@@ -210,6 +215,7 @@ case "$platform" in
esac
case "$target_cpu" in
arm) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARM=1" ;;
arm64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARM64=1" ;;
mips |mipsel) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;;
sparc64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
esac
@@ -416,6 +422,26 @@ esac
# For gnulib.
gl_INIT
WARN_FLAGS="-Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wpointer-arith -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wundef -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes"
EXTRA_WARN_FLAGS="-Wold-style-definition -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign"
HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align"
AC_CACHE_CHECK([which extra warnings work], [grub_cv_cc_w_extra_flags], [
SAVED_CFLAGS="$CFLAGS"
grub_cv_cc_w_extra_flags=
for x in $EXTRA_WARN_FLAGS; do
CFLAGS="$HOST_CFLAGS $x -Werror"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0])
if test x$flag = x1 ; then
grub_cv_cc_w_extra_flags="$grub_cv_cc_w_extra_flags $x"
fi
done
CFLAGS="$SAVED_CFLAGS"
])
HOST_CFLAGS="$HOST_CFLAGS $grub_cv_cc_w_extra_flags"
#
# Check for target programs.
#
@@ -466,8 +492,6 @@ LDFLAGS="$TARGET_LDFLAGS"
LIBS=""
# debug flags.
WARN_FLAGS="-Wall -W -Wshadow -Wold-style-definition -Wpointer-arith -Wundef -Wextra -Wattributes -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wendif-labels -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmultichar -Wnonnull -Woverflow -Wparentheses -Wpointer-arith -Wpointer-to-int-cast -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstrict-aliasing -Wswitch -Wtrigraphs -Wundef -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -Wnested-externs -Wstrict-prototypes -Wpointer-sign"
HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align"
TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations"
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g"
@@ -475,8 +499,25 @@ if test "x$target_cpu" != xi386 && test "x$target_cpu" != xx86_64; then
TARGET_CFLAGS="$TARGET_CFLAGS -Wcast-align"
fi
AC_CACHE_CHECK([which extra warnings work], [grub_cv_target_cc_w_extra_flags], [
LDFLAGS="$TARGET_LDFLAGS -nostdlib -static"
grub_cv_target_cc_w_extra_flags=
for x in $EXTRA_WARN_FLAGS; do
CFLAGS="$TARGET_CFLAGS $x -Werror"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0])
if test x$flag = x1 ; then
grub_cv_target_cc_w_extra_flags="$grub_cv_target_cc_w_extra_flags $x"
fi
done
])
TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_w_extra_flags"
AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang]
[AC_COMPILE_IFELSE(
[
CFLAGS="$TARGET_CFLAGS"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([], [[
#ifdef __clang__
#error "is clang"
@@ -486,10 +527,34 @@ AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang]
# on x86 clang doesn't support .code16
# on arm clang doesn't support .arch directive
if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 || test "x$target_cpu" = xarm ); then
# on mips clang doesn't support privilegied instructions, doubleword store/load
# and crashes with hand-written assembly
if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xi386 \
|| test "x$target_cpu" = xx86_64 || test "x$target_cpu" = xarm \
|| test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ); then
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as"
fi
if test "x$grub_cv_cc_target_clang" = xyes && test "x$target_cpu" = xpowerpc; then
AC_CACHE_CHECK([if clang can handle ame instruction], [grub_cv_cc_target_clang_ame]
[
CFLAGS="$TARGET_CFLAGS"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([], [[
unsigned int a = 0, b = 0;
asm volatile ("{ame|addme} %0,%1" : "=r" (a) : "r" (b));
if (a)
return 1;
]])],
[grub_cv_cc_target_clang_ame=yes], [grub_cv_cc_target_clang_ame=no])])
# clang <= 3.3 doesn't handle most of ppc assembly, not even inline assembly
# used by gcrypt
if test x$grub_cv_cc_target_clang_ame = xno ; then
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as"
TARGET_CFLAGS="$TARGET_CFLAGS -no-integrated-as"
fi
fi
if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then
TARGET_CFLAGS="$TARGET_CFLAGS -march=i386"
fi
@@ -516,6 +581,21 @@ if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test
TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3"
fi
# on mips redirect cache flushing function to non-existant one.
if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then
AC_CACHE_CHECK([whether -mflush-func=grub_red_herring works], [grub_cv_cc_mflush_func], [
CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_mflush_func=yes],
[grub_cv_cc_mflush_func=no])
])
if test "x$grub_cv_cc_mflush_func" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring"
fi
fi
# Force no alignment to save space on i386.
if test "x$target_cpu" = xi386; then
AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [
@@ -635,6 +715,30 @@ if test x"$efiemu_excuse" = x ; then
efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib"
fi
fi
if test x"$efiemu_excuse" = x ; then
AC_CACHE_CHECK([for efiemu64 linking format], [grub_cv_target_cc_efiemu64_link_format], [
grub_cv_target_cc_efiemu64_link_format=unknown
for format in -melf_x86_64 -melf_x86_64_fbsd -melf_x86_64_obsd -melf_x86_64_haiku -arch,x86_64; do
CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone"
LDFLAGS="-m64 -Wl,$format -nostdlib -static"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
asm (".globl start; start:");
asm (".globl _start; _start:");
asm (".globl __start; __start:");
void __main (void);
void __main (void) {}
]], [[]])], [flag=1], [flag=0])
if test x"$flag" = x1; then
grub_cv_target_cc_efiemu64_link_format="$format"
break;
fi
done])
if test x"$grub_cv_target_cc_efiemu64_link_format" = xunknown; then
efiemu_excuse="no suitable link format for efiemu64 found"
else
EFIEMU64_LINK_FORMAT="-Wl,$grub_cv_target_cc_efiemu64_link_format"
fi
fi
if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then
AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled])
fi
@@ -644,25 +748,26 @@ else
enable_efiemu=no
fi
AC_SUBST([enable_efiemu])
AC_SUBST([EFIEMU64_LINK_FORMAT])
CFLAGS="$TARGET_CFLAGS"
if test x"$target_cpu" = xi386 || test x"$target_cpu" = xx86_64; then
AC_CACHE_CHECK([for linking format], [grub_cv_target_cc_link_format], [
AC_CACHE_CHECK([for target linking format], [grub_cv_target_cc_link_format], [
grub_cv_target_cc_link_format=unknown
for format in -melf_${target_cpu} -melf_${target_cpu}_fbsd -melf_${target_cpu}_obsd -melf_${target_cpu}_haiku -m${target_cpu}pe -arch,${target_cpu}; do
if test x${target_cpu} != xi386 && test x$format = x${target_cpu}pe; then
continue
fi
CFLAGS="$TARGET_CFLAGS -static"
LDFLAGS="$TARGET_LDFLAGS -Wl,$format -nostdlib"
CFLAGS="$TARGET_CFLAGS"
LDFLAGS="$TARGET_LDFLAGS -Wl,$format -nostdlib -static"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
asm (".globl start; start:");
asm (".globl _start; _start:");
asm (".globl __start; __start:");
void __main (void);
void __main (void) {}
]], [[]])], [flag=1], [])
]], [[]])], [flag=1], [flag=0])
if test x"$flag" = x1; then
grub_cv_target_cc_link_format="$format"
break;
@@ -723,9 +828,7 @@ if test "$target_cpu" = x86_64; then
[grub_cv_cc_mcmodel=yes],
[grub_cv_cc_mcmodel=no])
])
if test "x$grub_cv_cc_mcmodel" = xno; then
AC_MSG_ERROR([-mcmodel=large not supported. Upgrade your gcc.])
else
if test "x$grub_cv_cc_mcmodel" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
fi
fi
@@ -745,6 +848,18 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then
TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone"
fi
if test "x$target_cpu" = xarm; then
AC_CACHE_CHECK([whether option -mlong-calls works], grub_cv_cc_mlong_calls, [
CFLAGS="$TARGET_CFLAGS -mlong-calls -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_mlong_calls=yes],
[grub_cv_cc_mlong_calls=no])
])
if test "x$grub_cv_cc_mlong_calls" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mlong-calls"
fi
fi
#
# Compiler features.
#
@@ -763,10 +878,17 @@ CFLAGS="$TARGET_CFLAGS"
# Position independent executable.
grub_CHECK_PIC
[# Need that, because some distributions ship compilers that include
# `-fPIC' in the default specs.
if [ x"$pic_possible" = xyes ]; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC"
[# On most platforms we don't want PIC as it only makes relocations harder
# and code less efficient. On mips we want to have one got table per module
# and reload $gp in every function.
# GCC implements it using symbol __gnu_local_gp in non-PIC as well.
# However with clang we need PIC for this reloading to happen.
# Since default varies across dictributions use either -fPIC or -fno-PIC
# explicitly.
if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel ) && test "x$grub_cv_cc_target_clang" = xyes ; then
TARGET_CFLAGS="$TARGET_CFLAGS -fPIC"
elif [ x"$pic_possible" = xyes ]; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC"
fi]
CFLAGS="$TARGET_CFLAGS"
@@ -790,18 +912,41 @@ fi
CFLAGS="$TARGET_CFLAGS"
# -mno-unaligned-access
# -mno-unaligned-access -mstrict-align
if test "$target_cpu" = arm; then
grub_CHECK_NO_UNALIGNED_ACCESS
if test x"$nua_possible" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mno-unaligned-access"
AC_CACHE_CHECK([for compile options to get strict alignment], [grub_cv_target_cc_strict_align], [
grub_cv_target_cc_strict_align=
for arg in -mno-unaligned-access "-Xclang -mstrict-align" -mstrict-align; do
CFLAGS="$TARGET_CFLAGS $arg -Werror"
LDFLAGS="$TARGET_LDFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0])
if test x"$flag" = x1; then
grub_cv_target_cc_strict_align="$arg"
break;
fi
done])
TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_strict_align"
if test x"$grub_cv_target_cc_strict_align" = x"-Xclang -mstrict-align"; then
TARGET_LDFLAGS="$TARGET_LDFLAGS -Qunused-arguments"
fi
AC_CACHE_CHECK([if compiler generates unaligned accesses], [grub_cv_cc_target_emits_unaligned],
[CFLAGS="$TARGET_CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
#ifdef __ARM_FEATURE_UNALIGNED
#error "unaligned"
#endif
]])],
[grub_cv_cc_target_emits_unaligned=no], [grub_cv_cc_target_emits_unaligned=yes])])
if test x$grub_cv_cc_target_emits_unaligned = xyes; then
AC_MSG_ERROR([compiler generates unaligned accesses])
fi
fi
# Set them to their new values for the tests below.
CC="$TARGET_CC"
if test "x$TARGET_APPLE_LINKER" = x1 ; then
CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error"
CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error"
else
CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error"
fi
@@ -827,7 +972,7 @@ fi
AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __ucmpdi2 _restgpr_14_x)
if test "x$TARGET_APPLE_LINKER" = x1 ; then
CFLAGS="$TARGET_CFLAGS -nostdlib"
CFLAGS="$TARGET_CFLAGS -nostdlib -static"
else
CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100"
fi
@@ -1125,8 +1270,8 @@ if test x"$grub_build_mkfont_excuse" = x ; then
else
enable_build_grub_mkfont=no
fi
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 ); then
AC_MSG_ERROR([qemu, powerpc-ieee1275 and loongson ports needs build-time grub-mkfont])
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont])
fi
AC_SUBST([build_freetype_cflags])
@@ -1179,6 +1324,11 @@ FONT_SOURCE=
for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc; do
if test -f "$dir/unifont.$ext"; then
md5="$(md5sum "$dir/unifont.$ext"|awk '{ print $1; }')"
# PCF and BDF from version 6.3 isn't hanled properly by libfreetype.
if test "$md5" = 0a54834d2788c83886a3e1785a6a1e61 || test "$md5" = 28f2565c7a41d8d407e2551159385edb || test "$md5" = dae5e588461b3b92b87b6ffee734f936 || test "$md5" = 4a3d687aa5bb329ed05f4263a1016791 ; then
continue;
fi
FONT_SOURCE="$dir/unifont.$ext"
break 2
fi
@@ -1189,8 +1339,8 @@ if test x"$enable_build_grub_mkfont" = xno ; then
FONT_SOURCE=
fi
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 ); then
AC_MSG_ERROR([qemu, powerpc-ieee1275 and loongson ports need unifont])
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont])
fi
AC_SUBST([FONT_SOURCE])
@@ -1434,6 +1584,8 @@ AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ])
AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot])
AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi])
AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ])
AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi])
AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
@@ -1450,6 +1602,12 @@ AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes])
AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes])
AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes])
AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
if test x$FONT_SOURCE != x ; then
HAVE_FONT_SOURCE=1
else
HAVE_FONT_SOURCE=0
fi
AC_SUBST(HAVE_FONT_SOURCE)
AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1])
AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes])
AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1])

View File

@@ -79,6 +79,7 @@ This edition documents version @value{VERSION}.
* Contributing Changes::
* Porting::
* Error Handling::
* Stack and heap size::
* BIOS port memory map::
* Video Subsystem::
* PFF2 Font File Format::
@@ -906,6 +907,69 @@ if (grub_errno != GRUB_ERR_NONE)
grub_error_pop ();
@end example
@node Stack and heap size
@chapter Stack and heap size
On emu stack and heap are just normal host OS stack and heap. Stack is typically
8 MiB although it's OS-dependent.
On i386-pc, i386-coreboot, i386-qemu and i386-multiboot the stack is 60KiB.
All available space between 1MiB and 4GiB marks is part of heap.
On *-xen stack is 4MiB. If compiled for x86-64 with GCC 4.4 or later adressable
space is unlimited. When compiled for x86-64 with older GCC version adressable
space is limited to 2GiB. When compiling for i386 adressable space is limited
to 4GiB. All adressable pages except the ones for stack, GRUB binary, special
pages and page table are in the heap.
On *-efi GRUB uses same stack as EFI. If compiled for x86-64 with GCC 4.4 or
later adressable space is unlimited. When compiled for x86-64 with older GCC
version adressable space is limited to 2GiB. For all other platforms adressable
space is limited to 4GiB. GRUB allocates pages from EFI for its heap, at most
1.6 GiB.
On i386-ieee1275 and powerpc-ieee1275 GRUB uses same stack as IEEE1275.
It allocates at most 32MiB for its heap.
On sparc64-ieee1275 stack is 256KiB and heap is 2MiB.
On mips(el)-qemu_mips and mipsel-loongson stack is 2MiB (everything below
GRUB image) and everything above GRUB image (from 2MiB + kernel size)
until 256MiB is part of heap.
On mips-arc stack is 2MiB (everything below GRUB image) and everything above
GRUB image(from 2MiB + kernel size) until 128MiB is part of heap.
On mipsel-arc stack is 2MiB (everything below GRUB image which is not part
of ARC) and everything above GRUB image (from 7MiB + kernel size)
until 256MiB is part of heap.
On arm-uboot stack is 256KiB and heap is 2MiB.
In short:
@multitable @columnfractions .15 .25 .5
@headitem Platform @tab Stack @tab Heap
@item emu @tab 8 MiB @tab ?
@item i386-pc @tab 60 KiB @tab < 4 GiB
@item i386-coreboot @tab 60 KiB @tab < 4 GiB
@item i386-multiboot @tab 60 KiB @tab < 4 GiB
@item i386-qemu @tab 60 KiB @tab < 4 GiB
@item *-efi @tab ? @tab < 1.6 GiB
@item i386-ieee1275 @tab ? @tab < 32 MiB
@item powerpc-ieee1275 @tab ? @tab < 32 MiB
@item sparc64-ieee1275 @tab 256KiB @tab 2 MiB
@item arm-uboot @tab 256KiB @tab 2 MiB
@item mips(el)-qemu_mips @tab 2MiB @tab 253 MiB
@item mipsel-loongson @tab 2MiB @tab 253 MiB
@item mips-arc @tab 2MiB @tab 125 MiB
@item mipsel-arc @tab 2MiB @tab 248 MiB
@item x86_64-xen (GCC >= 4.4) @tab 4MiB @tab unlimited
@item x86_64-xen (GCC < 4.4) @tab 4MiB @tab < 2GiB
@item i386-xen @tab 4MiB @tab < 4GiB
@end multitable
@node BIOS port memory map
@chapter BIOS port memory map
@c By Yoshinori K Okuji
@@ -917,9 +981,8 @@ grub_error_pop ();
@item ? @tab 0x2000 - 1 @tab Real mode stack
@item 0x7C00 @tab 0x7D00 - 1 @tab Boot sector
@item 0x8000 @tab ? @tab GRUB kernel
@item 0x68000 @tab 0x78000 - 1 @tab Disk buffer
@item 0x68000 @tab 0x71000 - 1 @tab Disk buffer
@item ? @tab 0x80000 - 1 @tab Protected mode stack
@item 0x80000 @tab ? @tab Heap
@item ? @tab 0xA0000 - 1 @tab Extended BIOS Data Area
@item 0xA0000 @tab 0xC0000 - 1 @tab Video RAM
@item 0xC0000 @tab 0x100000 - 1 @tab BIOS
@@ -1749,7 +1812,9 @@ right edges of two adjacent glyphs. The @strong{device width} field determines
the effective leading value that is used to render the font.
@end itemize
@image{font_char_metrics,,,,png}
@ifnottex
@image{font_char_metrics,,,,.png}
@end ifnottex
An illustration of how the various font metrics apply to characters.

View File

@@ -1298,23 +1298,26 @@ a key is pressed. The default is @samp{5}. Set to @samp{0} to boot
immediately without displaying the menu, or to @samp{-1} to wait
indefinitely.
@item GRUB_HIDDEN_TIMEOUT
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 @key{ESC} is
pressed.
Unset by default.
If @samp{GRUB_TIMEOUT_STYLE} is set to @samp{countdown} or @samp{hidden},
the timeout is instead counted before the menu is displayed.
@item GRUB_HIDDEN_TIMEOUT_QUIET
In conjunction with @samp{GRUB_HIDDEN_TIMEOUT}, set this to @samp{true} to
suppress the verbose countdown while waiting for a key to be pressed before
displaying the menu. Unset by default.
@item GRUB_TIMEOUT_STYLE
If this option is unset or set to @samp{menu}, then GRUB will display the
menu and then wait for the timeout set by @samp{GRUB_TIMEOUT} to expire
before booting the default entry. Pressing a key interrupts the timeout.
If this option is set to @samp{countdown} or @samp{hidden}, then, before
displaying the menu, GRUB will wait for the timeout set by
@samp{GRUB_TIMEOUT} to expire. If @key{ESC} is pressed during that time, it
will display the menu and wait for input. If a hotkey associated with a
menu entry is pressed, it will boot the associated menu entry immediately.
If the timeout expires before either of these happens, it will boot the
default entry. In the @samp{countdown} case, it will show a one-line
indication of the remaining time.
@item GRUB_DEFAULT_BUTTON
@itemx GRUB_TIMEOUT_BUTTON
@itemx GRUB_HIDDEN_TIMEOUT_BUTTON
@itemx GRUB_TIMEOUT_STYLE_BUTTON
@itemx GRUB_BUTTON_CMOS_ADDRESS
Variants of the corresponding variables without the @samp{_BUTTON} suffix,
used to support vendor-specific power buttons. @xref{Vendor power-on keys}.
@@ -1489,6 +1492,44 @@ Each module will be loaded as early as possible, at the start of
@end table
The following options are still accepted for compatibility with existing
configurations, but have better replacements:
@table @samp
@item GRUB_HIDDEN_TIMEOUT
Wait this many seconds before displaying the menu. If @key{ESC} is pressed
during that time, display the menu and wait for input according to
@samp{GRUB_TIMEOUT}. If a hotkey associated with a menu entry is pressed,
boot the associated menu entry immediately. If the timeout expires before
either of these happens, display the menu for the number of seconds
specified in @samp{GRUB_TIMEOUT} before booting the default entry.
If you set @samp{GRUB_HIDDEN_TIMEOUT}, you should also set
@samp{GRUB_TIMEOUT=0} so that the menu is not displayed at all unless
@key{ESC} is pressed.
This option is unset by default, and is deprecated in favour of the less
confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or
@samp{GRUB_TIMEOUT_STYLE=hidden}.
@item GRUB_HIDDEN_TIMEOUT_QUIET
In conjunction with @samp{GRUB_HIDDEN_TIMEOUT}, set this to @samp{true} to
suppress the verbose countdown while waiting for a key to be pressed before
displaying the menu.
This option is unset by default, and is deprecated in favour of the less
confusing @samp{GRUB_TIMEOUT_STYLE=countdown}.
@item GRUB_HIDDEN_TIMEOUT_BUTTON
Variant of @samp{GRUB_HIDDEN_TIMEOUT}, used to support vendor-specific power
buttons. @xref{Vendor power-on keys}.
This option is unset by default, and is deprecated in favour of the less
confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or
@samp{GRUB_TIMEOUT_STYLE=hidden}.
@end table
For more detailed customisation of @command{grub-mkconfig}'s output, you may
edit the scripts in @file{/etc/grub.d} directly.
@file{/etc/grub.d/40_custom} is particularly useful for adding entire custom
@@ -2477,15 +2518,16 @@ menu requires several fancy features of your terminal.
@node Vendor power-on keys
@chapter Using GRUB with vendor power-on keys
Some laptop vendors provide an additional power-on button which boots another
OS. GRUB supports such buttons with the @samp{GRUB_TIMEOUT_BUTTON},
@samp{GRUB_DEFAULT_BUTTON}, @samp{GRUB_HIDDEN_TIMEOUT_BUTTON} and
Some laptop vendors provide an additional power-on button which boots
another OS. GRUB supports such buttons with the @samp{GRUB_TIMEOUT_BUTTON},
@samp{GRUB_TIMEOUT_STYLE_BUTTON}, @samp{GRUB_DEFAULT_BUTTON}, and
@samp{GRUB_BUTTON_CMOS_ADDRESS} variables in default/grub (@pxref{Simple
configuration}). @samp{GRUB_TIMEOUT_BUTTON}, @samp{GRUB_DEFAULT_BUTTON} and
@samp{GRUB_HIDDEN_TIMEOUT_BUTTON} are used instead of the corresponding
variables without the @samp{_BUTTON} suffix when powered on using the special
button. @samp{GRUB_BUTTON_CMOS_ADDRESS} is vendor-specific and partially
model-specific. Values known to the GRUB team are:
configuration}). @samp{GRUB_TIMEOUT_BUTTON},
@samp{GRUB_TIMEOUT_STYLE_BUTTON}, and @samp{GRUB_DEFAULT_BUTTON} are used
instead of the corresponding variables without the @samp{_BUTTON} suffix
when powered on using the special button. @samp{GRUB_BUTTON_CMOS_ADDRESS}
is vendor-specific and partially model-specific. Values known to the GRUB
team are:
@table @key
@item Dell XPS M1330M
@@ -3030,6 +3072,7 @@ These variables have special meaning to GRUB.
* superusers::
* theme::
* timeout::
* timeout_style::
@end menu
@@ -3462,8 +3505,21 @@ keyboard input before booting the default menu entry. A timeout of @samp{0}
means to boot the default entry immediately without displaying the menu; a
timeout of @samp{-1} (or unset) means to wait indefinitely.
This variable is often set by @samp{GRUB_TIMEOUT} or
@samp{GRUB_HIDDEN_TIMEOUT} (@pxref{Simple configuration}).
If @samp{timeout_style} (@pxref{timeout_style}) is set to @samp{countdown}
or @samp{hidden}, the timeout is instead counted before the menu is
displayed.
This variable is often set by @samp{GRUB_TIMEOUT} (@pxref{Simple
configuration}).
@node timeout_style
@subsection timeout_style
This variable may be set to @samp{menu}, @samp{countdown}, or @samp{hidden}
to control the way in which the timeout (@pxref{timeout}) interacts with
displaying the menu. See the documentation of @samp{GRUB_TIMEOUT_STYLE}
(@pxref{Simple configuration}) for details.
@node Environment block
@@ -4420,7 +4476,7 @@ List devices or files.
With no arguments, print all devices known to GRUB.
If the argument is a device name enclosed in parentheses (@pxref{Device
syntax}), then list all files at the root directory of that device.
syntax}), then print the name of the filesystem of that device.
If the argument is a directory given as an absolute file name (@pxref{File
name syntax}), then list the contents of that directory.
@@ -4883,7 +4939,8 @@ Alias for @code{hashsum --hash sha512 arg @dots{}}. See command @command{hashsum
@deffn Command sleep [@option{--verbose}] [@option{--interruptible}] count
Sleep for @var{count} seconds. If option @option{--interruptible} is given,
allow @key{ESC} to interrupt sleep. With @option{--verbose} show countdown
of remaining seconds.
of remaining seconds. Exit code is set to 0 if timeout expired and to 1
if timeout was interrupted by @key{ESC}.
@end deffn

1020
gentpl.py

File diff suppressed because it is too large Load Diff

View File

@@ -10,10 +10,6 @@ CCAS=$(TARGET_CC)
RANLIB=$(TARGET_RANLIB)
STRIP=$(TARGET_STRIP)
if COND_HAVE_FONT_SOURCE
TARGET_CFLAGS += -DUSE_ASCII_FALLBACK=1 -DHAVE_UNIFONT_WIDTHSPEC=1
endif
MACHO2IMG=$(top_builddir)/grub-macho2img
AM_CFLAGS = $(TARGET_CFLAGS)
@@ -234,6 +230,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
endif
if COND_arm64_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
endif
if COND_emu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
@@ -388,41 +389,35 @@ CLEANFILES += $(MOD_FILES)
if COND_ENABLE_EFIEMU
efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
-rm -f $@; \
-rm -f $@
-rm -f $@.bin
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -static -O2 -c -o $@.bin $<
if test "x$(TARGET_APPLE_LINKER)" = x1; then \
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -O2 -c -o $@.bin $< || exit 1; \
$(OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \
rm -f $@.bin; \
$(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \
rm -f $@.bin ; \
elif test ! -z "$(TARGET_OBJ2ELF)"; then \
$(TARGET_OBJ2ELF) $@.bin || (rm -f $@.bin; exit 1); \
mv $@.bin $@ ; \
else \
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -O2 -c -o $@ $< || exit 1; \
if test ! -z "$(TARGET_OBJ2ELF)"; then $(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi; \
mv $@.bin $@ ; \
fi
# Link format -arch,x86_64 means Apple linker
efiemu64_c.o: efiemu/runtime/efiemu.c
if test "x$(TARGET_APPLE_LINKER)" = x1; then \
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -mno-red-zone -c -o $@ $< || exit 1; \
else \
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $< || exit 1; \
fi
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $<
efiemu64_s.o: efiemu/runtime/efiemu.S
-rm -f $@
if test "x$(TARGET_APPLE_LINKER)" = x1; then \
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mno-red-zone -c -o $@ $< || exit 1; \
else \
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $< || exit 1; \
fi
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $<
efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
-rm -f $@; \
if test "x$(TARGET_APPLE_LINKER)" = x1; then \
rm -f $@.bin; \
$(TARGET_CC) -m64 -Wl,-r -nostdlib -o $@.bin $^ || exit 1; \
$(OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \
-rm -f $@
-rm -f $@.bin
$(TARGET_CC) -m64 $(EFIEMU64_LINK_FORMAT) -nostdlib -static -Wl,-r -o $@.bin $^
if test "x$(EFIEMU64_LINK_FORMAT)" = x-arch,x86_64; then \
$(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \
rm -f $@.bin; \
else \
$(TARGET_CC) -m64 -Wl,-melf_x86_64 -nostdlib -Wl,-r -o $@ $^ || exit 1; \
if test ! -z "$(TARGET_OBJ2ELF)"; then $(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi; \
mv $@.bin $@ ; \
fi
platform_DATA += efiemu32.o efiemu64.o

View File

@@ -67,6 +67,9 @@ kernel = {
arm_efi_ldflags = '-Wl,-r,-d';
arm_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
arm64_efi_ldflags = '-Wl,-r,-d';
arm64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000';
@@ -85,7 +88,6 @@ kernel = {
mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000';
mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)';
mips_loongson_cppflags = '-DUSE_ASCII_FALLBACK';
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
emu_cflags = '$(CFLAGS_GNULIB)';
emu_cppflags = '$(CPPFLAGS_GNULIB)';
@@ -106,6 +108,7 @@ kernel = {
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
arm_uboot_startup = kern/arm/uboot/startup.S;
arm_efi_startup = kern/arm/efi/startup.S;
arm64_efi_startup = kern/arm64/efi/startup.S;
common = kern/command.c;
common = kern/corecmd.c;
@@ -194,6 +197,8 @@ kernel = {
arm_efi = kern/arm/efi/init.c;
arm_efi = kern/arm/efi/misc.c;
arm64_efi = kern/arm/efi/init.c;
i386_pc = kern/i386/pc/init.c;
i386_pc = kern/i386/pc/mmap.c;
i386_pc = term/i386/pc/console.c;
@@ -254,6 +259,11 @@ kernel = {
arm = kern/arm/cache.c;
arm = kern/arm/misc.S;
arm64 = kern/arm64/cache.c;
arm64 = kern/arm64/cache_flush.S;
arm64 = kern/arm64/dl.c;
arm64 = kern/arm64/dl_helper.c;
emu = disk/host.c;
emu = kern/emu/cache_s.S;
emu = kern/emu/hostdisk.c;
@@ -609,13 +619,6 @@ module = {
common = commands/i386/nthibr.c;
};
library = {
name = libgnulib.a;
common = gnulib/regex.c;
cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
};
module = {
name = cmostest;
common = commands/i386/cmostest.c;
@@ -667,8 +670,7 @@ module = {
name = regexp;
common = commands/regexp.c;
common = commands/wildcard.c;
ldadd = libgnulib.a;
dependencies = libgnulib.a;
common = gnulib/regex.c;
cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
};
@@ -751,6 +753,7 @@ module = {
enable = mips_arc;
enable = ia64_efi;
enable = arm_efi;
enable = arm64_efi;
enable = arm_uboot;
};
@@ -846,6 +849,7 @@ module = {
ia64_efi = lib/efi/reboot.c;
x86_64_efi = lib/efi/reboot.c;
arm_efi = lib/efi/reboot.c;
arm64_efi = lib/efi/reboot.c;
powerpc_ieee1275 = lib/ieee1275/reboot.c;
sparc64_ieee1275 = lib/ieee1275/reboot.c;
mips_arc = lib/mips/arc/reboot.c;
@@ -1566,6 +1570,7 @@ module = {
extra_dist = lib/ia64/setjmp.S;
extra_dist = lib/ia64/longjmp.S;
extra_dist = lib/arm/setjmp.S;
extra_dist = lib/arm64/setjmp.S;
};
module = {
@@ -1708,6 +1713,7 @@ module = {
enable = x86;
enable = ia64_efi;
enable = arm_efi;
enable = arm64_efi;
enable = mips;
};

View File

@@ -31,27 +31,32 @@
.macro floppy
part_start:
probe_values:
LOCAL(probe_values):
.byte 36, 18, 15, 9, 0
LOCAL(floppy_probe):
pushw %dx
/*
* Perform floppy probe.
*/
movw $probe_values - 1, %si
#ifdef __APPLE__
LOCAL(probe_values_minus_one) = LOCAL(probe_values) - 1
movw MACRO_DOLLAR(LOCAL(probe_values_minus_one)), %si
#else
movw MACRO_DOLLAR(LOCAL(probe_values)) - 1, %si
#endif
LOCAL(probe_loop):
/* reset floppy controller INT 13h AH=0 */
xorw %ax, %ax
int $0x13
int MACRO_DOLLAR(0x13)
incw %si
movb (%si), %cl
/* if number of sectors is 0, display error and die */
cmpb $0, %cl
jne 1f
testb %cl, %cl
jnz 1f
/*
* Floppy disk probe failure.
@@ -64,20 +69,20 @@ fd_probe_error_string: .asciz "Floppy"
1:
/* perform read */
movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
movw MACRO_DOLLAR(GRUB_BOOT_MACHINE_BUFFER_SEG), %bx
movw %bx, %es
xorw %bx, %bx
movw $0x201, %ax
movb $0, %ch
movb $0, %dh
int $0x13
movw MACRO_DOLLAR(0x201), %ax
movb MACRO_DOLLAR(0), %ch
movb MACRO_DOLLAR(0), %dh
int MACRO_DOLLAR(0x13)
/* if error, jump to "LOCAL(probe_loop)" */
jc LOCAL(probe_loop)
/* %cl is already the correct value! */
movb $1, %dh
movb $79, %ch
movb MACRO_DOLLAR(1), %dh
movb MACRO_DOLLAR(79), %ch
jmp LOCAL(final_init)
.endm
@@ -180,7 +185,9 @@ kernel_address:
#ifndef HYBRID_BOOT
. = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR
kernel_sector:
.long 1, 0
.long 1
kernel_sector_high:
.long 0
#endif
. = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE
@@ -285,7 +292,7 @@ lba_mode:
/* the absolute address */
movl kernel_sector, %ebx
movl %ebx, 8(%si)
movl kernel_sector + 4, %ebx
movl kernel_sector_high, %ebx
movl %ebx, 12(%si)
/* the segment of buffer address */
@@ -318,11 +325,12 @@ LOCAL(chs_mode):
int $0x13
jnc LOCAL(final_init)
popw %dx
/*
* The call failed, so maybe use the floppy probe instead.
*/
testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
jz LOCAL(floppy_probe)
testb %dl, %dl
jnb LOCAL(floppy_probe)
/* Nope, we definitely have a hard disk, and we're screwed. */
ERR(hd_probe_error_string)
@@ -353,7 +361,7 @@ LOCAL(final_init):
setup_sectors:
/* load logical sector start (top half) */
movl kernel_sector + 4, %eax
movl kernel_sector_high, %eax
orl %eax, %eax
jnz LOCAL(geometry_error)
@@ -505,7 +513,9 @@ LOCAL(message):
#ifdef HYBRID_BOOT
. = _start + 0x1b0
kernel_sector:
.long 1, 0
.long 1
kernel_sector_high:
.long 0
#endif
. = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
nt_magic:

View File

@@ -18,7 +18,6 @@
#include <config.h>
#include <grub/symbol.h>
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
#include <grub/machine/boot.h>
#include <grub/machine/kernel.h>

View File

@@ -27,6 +27,7 @@
.extern __bss_start
.extern _end
.extern _edata
.globl __start, _start, start
.set noreorder
@@ -248,8 +249,9 @@ cmdlinedone:
#include "../../kern/mips/cache_flush.S"
/* Decompress the payload. */
lui $a0, %hi(__bss_start)
addiu $a0, $a0, %lo(__bss_start)
lui $a0, %hi(_edata)
addiu $a0, $a0, %lo(_edata)
lui $t0, %hi(base)
addiu $t0, $t0, %lo(base)
subu $a0, $a0, $t0
@@ -265,16 +267,16 @@ cmdlinedone:
*/
move $s6, $a3
lui $t0, %hi(EXT_C(grub_decompress_core))
addiu $t0, $t0, %lo(EXT_C(grub_decompress_core))
lui $t9, %hi(EXT_C(grub_decompress_core))
addiu $t9, $t9, %lo(EXT_C(grub_decompress_core))
#ifdef GRUB_MACHINE_ARC
lui $sp, %hi(_start - 512)
jalr $t0
jalr $t9
addiu $sp, $sp, %lo(_start - 512)
#else
lui $sp, %hi(_start - 256)
jalr $t0
jalr $t9
addiu $sp, $sp, %lo(_start - 256)
#endif
move $a0, $s1
@@ -287,3 +289,11 @@ cmdlinedone:
jr $t1
nop
/* Ensure that .data section is created. In code we suppose that _edata
is first location not in decompressor image. Strictly speaking it's
_edata only when .data is present and _etext otherwise. But checking
for .data presence would cost more in code than it is to ensure that
.data is created.
*/
.data
.long 0

View File

@@ -48,7 +48,7 @@ kernel_byte: .xword (2 << 9)
boot_path_end:
kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
#else
#define boot_path (_start + 512)
#define boot_path (_start + 512 + SCRATCH_PAD_BOOT_SIZE)
#define boot_path_end (_start + 1024)
#include <grub/offsets.h>
@@ -140,7 +140,11 @@ prom_call:
boot_continue:
mov %o7, PIC_REG /* PIC base */
#ifndef CDBOOT
sethi %hi(SCRATCH_PAD_BOOT), %l1 /* OF argument slots */
#else
GET_ABS(_start + 512, %l1) /* OF argument slots */
#endif
/* Find the /chosen node so we can fetch the stdout handle,
* and thus perform console output.

View File

@@ -534,11 +534,20 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
"EHCI grub_ehci_pci_iter: registers above 4G are not supported\n");
return 0;
}
base &= GRUB_PCI_ADDR_MEM_MASK;
if (!base)
{
grub_dprintf ("ehci",
"EHCI: EHCI is not mapped\n");
return 0;
}
/* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word(addr,
GRUB_PCI_COMMAND_BUS_MASTER | grub_pci_read_word(addr));
GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER
| grub_pci_read_word(addr));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n");
}

View File

@@ -265,16 +265,20 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
base = grub_pci_read (addr);
#if 0
/* Stop if there is no IO space base address defined. */
if (! (base & 1))
return 0;
#endif
base &= GRUB_PCI_ADDR_MEM_MASK;
if (!base)
{
grub_dprintf ("ehci",
"EHCI: EHCI is not mapper\n");
return 0;
}
/* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word(addr,
GRUB_PCI_COMMAND_BUS_MASTER | grub_pci_read_word(addr));
GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER
| grub_pci_read_word(addr));
grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n",
class, subclass, interf);

View File

@@ -217,12 +217,6 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
if (class != 0x0c || subclass != 0x03 || interf != 0x00)
return 0;
/* Set bus master - needed for coreboot or broken BIOSes */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word(addr, GRUB_PCI_COMMAND_IO_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER
| grub_pci_read_word (addr));
/* Determine IO base address. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4);
base = grub_pci_read (addr);
@@ -233,6 +227,13 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
if ((base & GRUB_UHCI_IOMASK) == 0)
return 0;
/* Set bus master - needed for coreboot or broken BIOSes */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word(addr, GRUB_PCI_COMMAND_IO_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER
| GRUB_PCI_COMMAND_MEM_ENABLED
| grub_pci_read_word (addr));
grub_dprintf ("uhci", "base = %x\n", base);
/* Allocate memory for the controller and register it. */

View File

@@ -639,7 +639,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
grub_size_t size;
char *buf;
file = grub_file_open (args[i], GRUB_FILE_TYPE_ACPI_TABLE);
file = grub_file_open (args[i]);
if (! file)
{
free_tables ();

View File

@@ -121,8 +121,8 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (args[0], GRUB_FILE_TYPE_PRINT_BLOCKLIST
| GRUB_FILE_TYPE_NO_DECOMPRESS);
grub_file_filter_disable_compression ();
file = grub_file_open (args[0]);
if (! file)
return grub_errno;

View File

@@ -56,7 +56,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (args[0], GRUB_FILE_TYPE_CAT);
file = grub_file_open (args[0]);
if (! file)
return grub_errno;

View File

@@ -45,8 +45,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0],
args[1]);
file1 = grub_file_open (args[0], GRUB_FILE_TYPE_CMP);
file2 = grub_file_open (args[1], GRUB_FILE_TYPE_CMP);
file1 = grub_file_open (args[0]);
file2 = grub_file_open (args[1]);
if (! file1 || ! file2)
goto cleanup;

View File

@@ -169,7 +169,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
if (argc > 1)
{
file = grub_file_open (argv[1], GRUB_FILE_TYPE_VBE_DUMP);
file = grub_file_open (argv[1]);
if (! file)
return grub_errno;
@@ -183,7 +183,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
return grub_errno;
}
file = grub_file_open (argv[0], GRUB_FILE_TYPE_VBE_DUMP);
file = grub_file_open (argv[0]);
if (! file)
return grub_errno;

View File

@@ -113,7 +113,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
return grub_error (GRUB_ERR_BUG, "mdlen is too long");
hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST);
hashlist = grub_file_open (hashfilename);
if (!hashlist)
return grub_errno;
@@ -141,15 +141,17 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
filename = grub_xasprintf ("%s/%s", prefix, p);
if (!filename)
return grub_errno;
file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
: 0));
if (!uncompress)
grub_file_filter_disable_compression ();
file = grub_file_open (filename);
grub_free (filename);
}
else
file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
: 0));
{
if (!uncompress)
grub_file_filter_disable_compression ();
file = grub_file_open (p);
}
if (!file)
{
grub_file_close (hashlist);
@@ -240,9 +242,9 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
grub_file_t file;
grub_err_t err;
unsigned j;
file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
: 0));
if (!uncompress)
grub_file_filter_disable_compression ();
file = grub_file_open (args[i]);
if (!file)
{
if (!keep)

View File

@@ -90,7 +90,7 @@ grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args)
{
grub_file_t file;
file = grub_file_open (args[0], GRUB_FILE_TYPE_HEXCAT);
file = grub_file_open (args[0]);
if (! file)
return 0;

View File

@@ -39,7 +39,7 @@ grub_cmd_nthibr (grub_command_t cmd __attribute__ ((unused)),
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
hibr_file = grub_file_open (args[0], GRUB_FILE_TYPE_FILE_ID);
hibr_file = grub_file_open (args[0]);
if (!hibr_file)
return grub_errno;

View File

@@ -93,7 +93,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
grub_uint32_t tempo;
grub_file_t file;
file = grub_file_open (args[0], GRUB_FILE_TYPE_AUDIO);
file = grub_file_open (args[0]);
if (! file)
return grub_errno;

View File

@@ -218,7 +218,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
else
filename = argv[0];
file = grub_file_open (filename, GRUB_FILE_TYPE_KEYBOARD_LAYOUT);
file = grub_file_open (filename);
if (! file)
goto fail;

View File

@@ -55,7 +55,7 @@ legacy_file (const char *filename)
if (!suffix)
return grub_errno;
file = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG);
file = grub_file_open (filename);
if (! file)
return grub_errno;

View File

@@ -44,8 +44,7 @@ static const struct grub_arg_option options[] =
PUBKEY filter (that insists upon properly signed files) as well. PUBKEY
filter is restored before the function returns. */
static grub_file_t
open_envblk_file (char *filename,
enum grub_file_type type)
open_envblk_file (char *filename, int untrusted)
{
grub_file_t file;
char *buf = 0;
@@ -73,7 +72,13 @@ open_envblk_file (char *filename,
grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
}
file = grub_file_open (filename, type);
/* The filters that are disabled will be re-enabled by the call to
grub_file_open() after this particular file is opened. */
grub_file_filter_disable_compression ();
if (untrusted)
grub_file_filter_disable_pubkey ();
file = grub_file_open (filename);
grub_free (buf);
return file;
@@ -166,10 +171,7 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args)
whitelist.list = args;
/* state[0] is the -f flag; state[1] is the --skip-sig flag */
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
GRUB_FILE_TYPE_LOADENV
| (state[1].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE : 0));
file = open_envblk_file ((state[0].set) ? state[0].arg : 0, state[1].set);
if (! file)
return grub_errno;
@@ -204,10 +206,7 @@ grub_cmd_list_env (grub_extcmd_context_t ctxt,
grub_file_t file;
grub_envblk_t envblk;
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
GRUB_FILE_TYPE_LOADENV
| (state[1].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE : 0));
file = open_envblk_file ((state[0].set) ? state[0].arg : 0, 0);
if (! file)
return grub_errno;
@@ -400,8 +399,7 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified");
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
GRUB_FILE_TYPE_SAVEENV
| GRUB_FILE_TYPE_SKIP_SIGNATURE);
1 /* allow untrusted */);
if (! file)
return grub_errno;

View File

@@ -129,8 +129,8 @@ print_files_long (const char *filename, const struct grub_dirhook_info *info,
/* XXX: For ext2fs symlinks are detected as files while they
should be reported as directories. */
file = grub_file_open (pathname, GRUB_FILE_TYPE_GET_SIZE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
grub_file_filter_disable_compression ();
file = grub_file_open (pathname);
if (! file)
{
grub_errno = 0;
@@ -225,8 +225,8 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
struct grub_dirhook_info info;
grub_errno = 0;
file = grub_file_open (dirname, GRUB_FILE_TYPE_GET_SIZE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
grub_file_filter_disable_compression ();
file = grub_file_open (dirname);
if (! file)
goto fail;

View File

@@ -43,7 +43,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (argv[0], GRUB_FILE_TYPE_CAT);
file = grub_file_open (argv[0]);
if (! file)
return grub_errno;

View File

@@ -234,8 +234,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
if (! filename)
goto fail;
file = grub_file_open (filename,
GRUB_FILE_TYPE_GRUB_MODULE);
file = grub_file_open (filename);
grub_free (filename);
if (! file)
goto fail;

View File

@@ -193,7 +193,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
{
grub_file_t file;
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST);
file = grub_file_open (filename);
if (file)
{
char *buf = 0;

View File

@@ -81,8 +81,8 @@ iterate_device (const char *name, void *data)
if (! buf)
return 1;
file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH
| GRUB_FILE_TYPE_NO_DECOMPRESS);
grub_file_filter_disable_compression ();
file = grub_file_open (buf);
if (file)
{
found = 1;

View File

@@ -355,8 +355,8 @@ test_parse (char **args, int *argn, int argc)
if (grub_strcmp (args[*argn], "-s") == 0)
{
grub_file_t file;
file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
grub_file_filter_disable_compression ();
file = grub_file_open (args[*argn + 1]);
update_val (file && (grub_file_size (file) != 0), &ctx);
if (file)
grub_file_close (file);

View File

@@ -57,7 +57,7 @@ grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)),
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (argv[0], GRUB_FILE_TYPE_TESTLOAD);
file = grub_file_open (argv[0]);
if (! file)
return grub_errno;

View File

@@ -61,7 +61,7 @@ grub_cmd_testspeed (grub_extcmd_context_t ctxt, int argc, char **args)
if (buffer == NULL)
return grub_errno;
file = grub_file_open (args[0], GRUB_FILE_TYPE_TESTLOAD);
file = grub_file_open (args[0]);
if (file == NULL)
goto quit;

View File

@@ -30,7 +30,6 @@
#include <grub/env.h>
#include <grub/kernel.h>
#include <grub/extcmd.h>
#include <grub/efi/pe32.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -433,356 +432,6 @@ rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
return ret;
}
static grub_err_t
get (char *buf, grub_size_t size,
grub_file_t f, void *out,
grub_off_t off, grub_size_t sz)
{
if (buf)
{
if (off > ~(grub_uint32_t) sz
|| off + sz > size)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
grub_memcpy (out, buf + off, sz);
return GRUB_ERR_NONE;
}
if (grub_file_seek (f, off) == (grub_size_t) -1)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
if (grub_file_read (f, out, sz) != (grub_ssize_t) sz)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
return GRUB_ERR_NONE;
}
static grub_err_t
read_len (char *buf, grub_size_t size,
grub_file_t f, grub_off_t *curoff, grub_uint32_t *endoff)
{
grub_uint8_t cb;
unsigned ss, rl;
grub_uint32_t v = 0;
grub_err_t err;
err = get (buf, size, f, &cb, (*curoff)++, 1);
if (err)
return err;
if (!(cb & 0x80))
{
*endoff = *curoff + (cb & 0x7f);
return GRUB_ERR_NONE;
}
ss = cb & 0x7f;
if (ss > 4)
rl = 4;
else
rl = ss;
*curoff += (ss - rl);
err = get (buf, size, f, (char *) &v + (4 - rl), *curoff,
rl);
if (err)
return err;
*curoff += rl;
*endoff = *curoff + (grub_be_to_cpu32 (v) & 0x7fffff);
return GRUB_ERR_NONE;
}
#define MAX_FULLASN 128
static grub_err_t
grub_verify_pe_signature_real (char *buf, grub_size_t size,
grub_file_t f,
struct grub_public_key *pkey)
{
grub_uint8_t mz[2];
const gcry_md_spec_t *hash;
grub_uint32_t coff_offset, opt_offset;
union
{
struct grub_pe32_optional_header o32;
struct grub_pe64_optional_header o64;
} opt_head;
struct grub_pe32_data_directory *certtab;
grub_err_t err;
void *context = NULL;
void *read_buf = NULL;
grub_uint8_t *hval;
grub_off_t curoff;
grub_uint8_t cb;
grub_uint8_t full_asn[MAX_FULLASN];
/*
hash as:
offs[0] - offs[1]
skip: checksum
offs[2] - offs[3]
skip: cert entry
offs[4] - offs[5]
skip: cert
offs[6] - offs[7]
*/
grub_uint32_t offs[8];
grub_uint32_t endoff[5];
grub_uint32_t full_asn_offset, full_asn_offset_end;
grub_size_t i;
err = get (buf, size, f, mz, 0, 2);
if (err)
return err;
if (mz[0] != 'M' || mz[1] != 'Z')
goto fail;
err = get (buf, size, f, &coff_offset, 0x3c, 4);
if (err)
return err;
opt_offset = grub_cpu_to_le32 (coff_offset) + sizeof (struct grub_pe32_coff_header) + 4;
err = get (buf, size, f, &opt_head, opt_offset, sizeof (opt_head));
if (err)
return err;
grub_dprintf ("crypt", "opt_offset = %x\n", (int) opt_offset);
if (opt_head.o32.magic == grub_cpu_to_le16_compile_time (GRUB_PE32_PE32_MAGIC))
{
offs[1] = (char *) &opt_head.o32.checksum - (char *) &opt_head + opt_offset;
certtab = &opt_head.o32.certificate_table;
}
else if (opt_head.o64.magic == grub_cpu_to_le16_compile_time (GRUB_PE32_PE64_MAGIC))
{
offs[1] = (char *) &opt_head.o64.checksum - (char *) &opt_head + opt_offset;
certtab = &opt_head.o64.certificate_table;
}
else
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
if (certtab->size == 0)
goto fail;
offs[0] = 0;
offs[2] = offs[1] + 4;
offs[3] = (char *) certtab - (char *) &opt_head + opt_offset;
offs[4] = offs[3] + sizeof (*certtab);
offs[5] = grub_le_to_cpu32 (certtab->rva);
offs[6] = offs[5] + grub_le_to_cpu32 (certtab->size);
offs[7] = buf ? size : grub_file_size (f);
/* Verify that offset sequence is valid. */
for (i = 0; i < 7; i++)
if (offs[i + 1] < offs[i])
goto fail;
grub_dprintf ("crypt", "sig @%x+%x\n", (int)certtab->rva,
(int)certtab->size);
curoff = grub_le_to_cpu32 (certtab->rva) + 8;
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0x30)
goto fail;
/* into. */
err = read_len (buf, size, f, &curoff, &endoff[0]);
if (err)
return err;
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0x06)
goto fail;
/* skip. */
err = read_len (buf, size, f, &curoff, &endoff[1]);
if (err)
return err;
curoff = endoff[1];
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0xa0)
goto fail;
/* into. */
err = read_len (buf, size, f, &curoff, &endoff[1]);
if (err)
return err;
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0x30)
goto fail;
/* into. */
err = read_len (buf, size, f, &curoff, &endoff[2]);
if (err)
return err;
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0x02)
goto fail;
/* skip */
err = read_len (buf, size, f, &curoff, &endoff[2]);
if (err)
return err;
curoff = endoff[2];
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0x31)
goto fail;
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0x0f)
goto fail;
err = read_len (buf, size, f, &curoff, &endoff[3]);
if (err)
return err;
curoff = endoff[3];
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0x03)
goto fail;
err = read_len (buf, size, f, &curoff, &endoff[3]);
if (err)
return err;
curoff = endoff[3];
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0xa0)
goto fail;
err = read_len (buf, size, f, &curoff, &endoff[3]);
if (err)
return err;
curoff = endoff[3];
grub_dprintf ("crypt", "off: %x\n",
(int)curoff - grub_le_to_cpu32 (certtab->rva));
/* At this point we have the full ASN at current offset */
full_asn_offset = curoff;
err = get (buf, size, f, &cb, curoff++, 1);
if (err)
return err;
if (cb != 0x30)
goto fail;
err = read_len (buf, size, f, &curoff, &endoff[3]);
if (err)
return err;
curoff = endoff[3];
full_asn_offset_end = curoff;
grub_dprintf ("crypt", "off: %x\n",
(int)full_asn_offset_end - grub_le_to_cpu32 (certtab->rva));
if (full_asn_offset_end - full_asn_offset > MAX_FULLASN)
goto fail;
err = get (buf, size, f, full_asn, full_asn_offset,
full_asn_offset_end - full_asn_offset);
if (err)
return err;
hash = grub_crypto_lookup_md_by_asn (full_asn,
full_asn_offset_end - full_asn_offset);
if (!hash)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash not loaded");
if (hash->asnlen + hash->mdlen != full_asn_offset_end - full_asn_offset)
goto fail;
context = grub_zalloc (hash->contextsize);
if (!context)
goto fail;
hash->init (context);
if (buf)
{
for (i = 0; i <= 3; i++)
hash->write (context, buf + offs[2 * i],
offs[2 * i + 1] - offs[2 * i]);
}
else
{
read_buf = grub_malloc (READBUF_SIZE);
for (i = 0; i <= 3; i++)
{
grub_size_t rem;
grub_ssize_t r;
if (grub_file_seek (f, offs[2 * i]) == (grub_size_t) -1)
goto fail;
rem = offs[2 * i + 1] - offs[2 * i];
COMPILE_TIME_ASSERT (sizeof (rem) >= sizeof (offs[0]));
while (rem)
{
r = grub_file_read (f, read_buf,
rem < READBUF_SIZE ? rem : READBUF_SIZE);
if (r < 0)
goto fail;
if (r == 0)
break;
hash->write (context, read_buf, r);
rem -= r;
}
if (rem)
goto fail;
}
}
hash->final (context);
hval = hash->read (context);
if (grub_memcmp (full_asn + hash->asnlen,
hval, hash->mdlen) != 0)
goto fail;
for (i = 0; i < hash->mdlen; i++)
grub_printf ("%02x ", hval[i]);
grub_printf ("\n");
(void) pkey;
return GRUB_ERR_NONE;
fail:
grub_free (context);
grub_free (read_buf);
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
}
static grub_err_t
grub_verify_signature_real (char *buf, grub_size_t size,
grub_file_t f, grub_file_t sig,
@@ -881,8 +530,6 @@ grub_verify_signature_real (char *buf, grub_size_t size,
hash->write (context, readbuf, r);
rem -= r;
}
if (rem)
goto fail;
hash->write (context, &v, sizeof (v));
s = 0xff;
hash->write (context, &s, sizeof (s));
@@ -1020,12 +667,10 @@ grub_cmd_trust (grub_extcmd_context_t ctxt,
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
pkf = grub_file_open (args[0],
GRUB_FILE_TYPE_PUBLIC_KEY_TRUST
| GRUB_FILE_TYPE_NO_DECOMPRESS
| (ctxt->state[OPTION_SKIP_SIG].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE
: 0));
grub_file_filter_disable_compression ();
if (ctxt->state[OPTION_SKIP_SIG].set)
grub_file_filter_disable_pubkey ();
pkf = grub_file_open (args[0]);
if (!pkf)
return grub_errno;
pk = grub_load_public_key (pkf);
@@ -1113,12 +758,10 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
if (argc > 2)
{
grub_file_t pkf;
pkf = grub_file_open (args[2],
GRUB_FILE_TYPE_PUBLIC_KEY
| GRUB_FILE_TYPE_NO_DECOMPRESS
| (ctxt->state[OPTION_SKIP_SIG].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE
: 0));
grub_file_filter_disable_compression ();
if (ctxt->state[OPTION_SKIP_SIG].set)
grub_file_filter_disable_pubkey ();
pkf = grub_file_open (args[2]);
if (!pkf)
return grub_errno;
pk = grub_load_public_key (pkf);
@@ -1130,16 +773,16 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
grub_file_close (pkf);
}
f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
grub_file_filter_disable_all ();
f = grub_file_open (args[0]);
if (!f)
{
err = grub_errno;
goto fail;
}
sig = grub_file_open (args[1],
GRUB_FILE_TYPE_SIGNATURE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
grub_file_filter_disable_all ();
sig = grub_file_open (args[1]);
if (!sig)
{
err = grub_errno;
@@ -1157,57 +800,6 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
return err;
}
static grub_err_t
grub_cmd_verify_pe_signature (grub_extcmd_context_t ctxt,
int argc, char **args)
{
grub_file_t f = NULL;
grub_err_t err = GRUB_ERR_NONE;
struct grub_public_key *pk = NULL;
grub_dprintf ("crypt", "alive\n");
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
grub_dprintf ("crypt", "alive\n");
if (argc > 1)
{
grub_file_t pkf;
pkf = grub_file_open (args[1],
GRUB_FILE_TYPE_PUBLIC_KEY
| GRUB_FILE_TYPE_NO_DECOMPRESS
| (ctxt->state[OPTION_SKIP_SIG].set
? GRUB_FILE_TYPE_SKIP_SIGNATURE
: 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);
}
f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
if (!f)
{
err = grub_errno;
goto fail;
}
err = grub_verify_pe_signature_real (0, 0, f, pk);
fail:
if (f)
grub_file_close (f);
if (pk)
free_pk (pk);
return err;
}
static int sec = 0;
static grub_ssize_t
@@ -1233,25 +825,33 @@ struct grub_fs verified_fs =
};
static grub_file_t
grub_pubkey_open (grub_file_t io, enum grub_file_type type)
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];
grub_file_t ret;
if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE
|| (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE
|| (type & GRUB_FILE_TYPE_SKIP_SIGNATURE))
return io;
if (!sec)
return io;
if (io->device->disk && io->device->disk->id == GRUB_DISK_DEVICE_MEMDISK_ID)
return io;
fsuf = grub_malloc (grub_strlen (io->name) + sizeof (".sig"));
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;
ret = grub_malloc (sizeof (*ret));
if (!ret)
@@ -1276,30 +876,12 @@ grub_pubkey_open (grub_file_t io, enum grub_file_type type)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
io->name);
filename);
return NULL;
}
ptr = grub_stpcpy (fsuf, io->name);
grub_memcpy (ptr, ".sig", sizeof (".sig"));
sig = grub_file_open (fsuf, GRUB_FILE_TYPE_SIGNATURE);
grub_free (fsuf);
if (!sig)
grub_errno = GRUB_ERR_NONE;
if (sig)
{
err = grub_verify_signature_real (ret->data, ret->size, 0, sig, NULL);
grub_file_close (sig);
if (err == GRUB_ERR_BAD_SIGNATURE)
{
grub_errno = GRUB_ERR_NONE;
err = grub_verify_pe_signature_real (ret->data, ret->size, 0, 0);
}
}
else
err = grub_verify_pe_signature_real (ret->data, ret->size, 0, 0);
err = grub_verify_signature_real (ret->data, ret->size, 0, sig, NULL);
grub_file_close (sig);
if (err)
return NULL;
io->device = 0;
@@ -1381,10 +963,6 @@ GRUB_MOD_INIT(verify)
N_("[-s|--skip-sig] FILE SIGNATURE_FILE [PUBKEY_FILE]"),
N_("Verify detached signature."),
options);
cmd = grub_register_extcmd ("verify_pe", grub_cmd_verify_pe_signature, 0,
N_("[-s|--skip-sig] FILE [PUBKEY_FILE]"),
N_("Verify PE signature."),
options);
cmd_trust = grub_register_extcmd ("trust", grub_cmd_trust, 0,
N_("[-s|--skip-sig] PUBKEY_FILE"),
N_("Add PKFILE to trusted keys."),

View File

@@ -426,6 +426,10 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
disk->total_sectors = total_sectors;
/* Limit the max to 0x7f because of Phoenix EDD. */
disk->max_agglomerate = 0x7f >> GRUB_DISK_CACHE_BITS;
COMPILE_TIME_ASSERT ((0x7f >> GRUB_DISK_CACHE_BITS
<< (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS))
+ sizeof (struct grub_biosdisk_dap)
< GRUB_MEMORY_MACHINE_SCRATCH_SIZE);
disk->data = data;

View File

@@ -31,11 +31,14 @@ static grub_ieee1275_ihandle_t last_ihandle;
struct ofdisk_hash_ent
{
char *devpath;
char *open_path;
char *grub_devpath;
int is_boot;
int is_cdrom;
/* Pointer to shortest available name on nodes representing canonical names,
otherwise NULL. */
const char *shortest;
const char *grub_shortest;
struct ofdisk_hash_ent *next;
};
@@ -70,12 +73,50 @@ ofdisk_hash_add_real (char *devpath)
{
struct ofdisk_hash_ent *p;
struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
const char *iptr;
char *optr;
p = grub_zalloc (sizeof (*p));
if (!p)
return NULL;
p->devpath = devpath;
p->grub_devpath = grub_malloc (sizeof ("ieee1275/")
+ 2 * grub_strlen (p->devpath));
if (!p->grub_devpath)
{
grub_free (p);
return NULL;
}
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
{
p->open_path = grub_malloc (grub_strlen (p->devpath) + 3);
if (!p->open_path)
{
grub_free (p->grub_devpath);
grub_free (p);
return NULL;
}
optr = grub_stpcpy (p->open_path, p->devpath);
*optr++ = ':';
*optr++ = '0';
*optr = '\0';
}
else
p->open_path = p->devpath;
optr = grub_stpcpy (p->grub_devpath, "ieee1275/");
for (iptr = p->devpath; *iptr; )
{
if (*iptr == ',')
*optr++ = '\\';
*optr++ = *iptr++;
}
*optr = 0;
p->next = *head;
*head = p;
return p;
@@ -104,7 +145,8 @@ ofdisk_hash_add (char *devpath, char *curcan)
if (!curcan)
{
p->shortest = devpath;
p->shortest = p->devpath;
p->grub_shortest = p->grub_devpath;
if (check_string_cdrom (devpath))
p->is_cdrom = 1;
return p;
@@ -125,7 +167,10 @@ ofdisk_hash_add (char *devpath, char *curcan)
{
if (!pcan->shortest
|| grub_strlen (pcan->shortest) > grub_strlen (devpath))
pcan->shortest = devpath;
{
pcan->shortest = p->devpath;
pcan->grub_shortest = p->grub_devpath;
}
}
return p;
@@ -288,21 +333,8 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
if (!ent->is_boot && ent->is_cdrom)
continue;
{
char buffer[sizeof ("ieee1275/") + 2 * grub_strlen (ent->shortest)];
const char *iptr;
char *optr;
optr = grub_stpcpy (buffer, "ieee1275/");
for (iptr = ent->shortest; *iptr; )
{
if (*iptr == ',')
*optr++ = '\\';
*optr++ = *iptr++;
}
*optr = 0;
if (hook (buffer, hook_data))
return 1;
}
if (hook (ent->grub_shortest, hook_data))
return 1;
}
}
return 0;
@@ -396,7 +428,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
if (!op)
return grub_errno;
disk->id = (unsigned long) op;
disk->data = op->devpath;
disk->data = op->open_path;
}
return 0;
@@ -428,20 +460,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector)
last_ihandle = 0;
last_devpath = NULL;
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
{
char name2[grub_strlen (disk->data) + 3];
char *p;
grub_strcpy (name2, disk->data);
p = name2 + grub_strlen (name2);
*p++ = ':';
*p++ = '0';
*p = 0;
grub_ieee1275_open (name2, &last_ihandle);
}
else
grub_ieee1275_open (disk->data, &last_ihandle);
grub_ieee1275_open (disk->data, &last_ihandle);
if (! last_ihandle)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
last_devpath = disk->data;

View File

@@ -90,8 +90,7 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
if (argc < 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
file = grub_file_open (args[1], GRUB_FILE_TYPE_LOOPBACK
| GRUB_FILE_TYPE_NO_DECOMPRESS);
file = grub_file_open (args[1]);
if (! file)
return grub_errno;

View File

@@ -402,9 +402,15 @@ grub_pata_pciinit (grub_pci_device_t dev,
bar2 = grub_pci_read (addr);
/* Check if the BARs describe an IO region. */
if ((bar1 & 1) && (bar2 & 1))
if ((bar1 & 1) && (bar2 & 1) && (bar1 & ~3))
{
rega = bar1 & ~3;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word (addr, grub_pci_read_word (addr)
| GRUB_PCI_COMMAND_IO_ENABLED
| GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER);
}
}

View File

@@ -33,7 +33,7 @@
GRUB_MOD_LICENSE ("GPLv3+");
#ifdef USE_ASCII_FALLBACK
#if HAVE_FONT_SOURCE
#include "ascii.h"
#endif
@@ -110,43 +110,65 @@ static struct grub_font null_font;
/* Flag to ensure module is initialized only once. */
static grub_uint8_t font_loader_initialized;
#ifdef USE_ASCII_FALLBACK
static struct grub_font_glyph *ascii_font_glyph[0x80];
#if HAVE_FONT_SOURCE
static struct grub_font_glyph *ascii_font_glyph[ASCII_NUM];
static struct grub_font_glyph *arrows_font_glyph[ARROWS_NUM];
static struct grub_font_glyph *lines_font_glyph[LINES_NUM];
static void
init_fallback (struct grub_font_glyph **glyphs, const unsigned char *stored,
grub_uint32_t len)
{
grub_uint32_t current;
for (current = 0; current < len; current++)
{
glyphs[current] =
grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE);
if (!glyphs[current])
{
grub_errno = GRUB_ERR_NONE;
continue;
}
glyphs[current]->width = 8;
glyphs[current]->height = 16;
glyphs[current]->offset_x = 0;
glyphs[current]->offset_y = -2;
glyphs[current]->device_width = 8;
glyphs[current]->font = NULL;
grub_memcpy (glyphs[current]->bitmap,
&stored[current * ASCII_BITMAP_SIZE],
ASCII_BITMAP_SIZE);
}
}
#endif
static struct grub_font_glyph *
ascii_glyph_lookup (grub_uint32_t code)
{
#ifdef USE_ASCII_FALLBACK
static int ascii_failback_initialized = 0;
#if HAVE_FONT_SOURCE
static int ascii_fallback_initialized = 0;
struct grub_font_glyph **p;
if (code >= 0x80)
if (code < ASCII_NUM)
p = &ascii_font_glyph[code];
else if (code >= ARROWS_START && code < ARROWS_START + ARROWS_NUM)
p = &arrows_font_glyph[code - ARROWS_START];
else if (code >= LINES_START && code < LINES_START + LINES_NUM)
p = &lines_font_glyph[code - LINES_START];
else
return NULL;
if (ascii_failback_initialized == 0)
if (ascii_fallback_initialized == 0)
{
int current;
for (current = 0; current < 0x80; current++)
{
ascii_font_glyph[current] =
grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE);
ascii_font_glyph[current]->width = 8;
ascii_font_glyph[current]->height = 16;
ascii_font_glyph[current]->offset_x = 0;
ascii_font_glyph[current]->offset_y = -2;
ascii_font_glyph[current]->device_width = 8;
ascii_font_glyph[current]->font = NULL;
grub_memcpy (ascii_font_glyph[current]->bitmap,
&ascii_bitmaps[current * ASCII_BITMAP_SIZE],
ASCII_BITMAP_SIZE);
}
ascii_failback_initialized = 1;
init_fallback (ascii_font_glyph, ascii_bitmaps, ASCII_NUM);
init_fallback (arrows_font_glyph, arrows_bitmaps, ARROWS_NUM);
init_fallback (lines_font_glyph, lines_bitmaps, LINES_NUM);
ascii_fallback_initialized = 1;
}
return ascii_font_glyph[code];
return *p;
#else
(void) code;
return NULL;
@@ -418,7 +440,7 @@ grub_font_load (const char *filename)
#endif
if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+')
file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024);
file = grub_buffile_open (filename, 1024);
else
{
const char *prefix = grub_env_get ("prefix");
@@ -438,7 +460,7 @@ grub_font_load (const char *filename)
ptr = grub_stpcpy (ptr, filename);
ptr = grub_stpcpy (ptr, ".pf2");
*ptr = 0;
file = grub_buffile_open (fullname, GRUB_FILE_TYPE_FONT, 1024);
file = grub_buffile_open (fullname, 1024);
grub_free (fullname);
}
if (!file)

View File

@@ -418,7 +418,7 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args)
if (argc > 0)
{
grub_file_t file;
file = grub_file_open (args[0], GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY);
file = grub_file_open (args[0]);
if (!file)
return grub_errno;
real_size = grub_file_read (file, buf, 1024);

View File

@@ -71,11 +71,7 @@ VARIABLE(grub_gdb_stack)
#define REG \reg
#define NDX \ndx
#endif
#ifdef __APPLE__
xorl %eax, %eax
#else
movl $0, %eax
#endif
movw REG, EXT_C(grub_gdb_regs)+(NDX * 4)
movw %ax, EXT_C(grub_gdb_regs)+(NDX * 4 + 2)
movl EXT_C(grub_gdb_regs)+(EAX * 4), %eax
@@ -190,11 +186,7 @@ VARIABLE(grub_gdb_stack)
.text
1:
.if EC
#ifdef __APPLE__
add $$4, %esp
#else
add $4, %esp
#endif
add MACRO_DOLLAR(4), %esp
.endif
save_context

View File

@@ -23,7 +23,7 @@ BEGIN {
} else if ($1 == "undefined") {
if ($3 in symtab)
modtab[$2] = modtab[$2] " " symtab[$3];
else if ($3 != "__gnu_local_gp") {
else if ($3 != "__gnu_local_gp" && $3 != "_gp_disp") {
printf "%s in %s is not defined\n", $3, $2 >"/dev/stderr";
error++;
}

View File

@@ -291,7 +291,7 @@ grub_mofile_open (struct grub_gettext_context *ctx,
/* Using fd_mo and not another variable because
it's needed for grub_gettext_get_info. */
fd = grub_file_open (filename, GRUB_FILE_TYPE_GETTEXT_CATALOG);
fd = grub_file_open (filename);
if (!fd)
return grub_errno;

View File

@@ -743,7 +743,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
p.view = view;
p.theme_dir = grub_get_dirname (theme_path);
file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME);
file = grub_file_open (theme_path);
if (! file)
{
grub_free (p.theme_dir);

View File

@@ -43,8 +43,7 @@ typedef struct grub_bufio *grub_bufio_t;
static struct grub_fs grub_bufio_fs;
grub_file_t
grub_bufio_open (grub_file_t io,
grub_size_t size)
grub_bufio_open (grub_file_t io, int size)
{
grub_file_t file;
grub_bufio_t bufio = 0;
@@ -58,7 +57,7 @@ grub_bufio_open (grub_file_t io,
else if (size > GRUB_BUFIO_MAX_SIZE)
size = GRUB_BUFIO_MAX_SIZE;
if (size > io->size)
if ((size < 0) || ((unsigned) size > io->size))
size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE :
io->size);
@@ -82,12 +81,11 @@ grub_bufio_open (grub_file_t io,
}
grub_file_t
grub_buffile_open (const char *name, enum grub_file_type type,
grub_size_t size)
grub_buffile_open (const char *name, int size)
{
grub_file_t io, file;
io = grub_file_open (name, type);
io = grub_file_open (name);
if (! io)
return 0;

View File

@@ -1125,14 +1125,11 @@ 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, enum grub_file_type type)
grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused)))
{
grub_file_t file;
grub_gzio_t gzio = 0;
if (type & GRUB_FILE_TYPE_NO_DECOMPRESS)
return io;
file = (grub_file_t) grub_zalloc (sizeof (*file));
if (! file)
return 0;

View File

@@ -409,14 +409,12 @@ CORRUPTED:
}
static grub_file_t
grub_lzopio_open (grub_file_t io, enum grub_file_type type)
grub_lzopio_open (grub_file_t io,
const char *name __attribute__ ((unused)))
{
grub_file_t file;
grub_lzopio_t lzopio;
if (type & GRUB_FILE_TYPE_NO_DECOMPRESS)
return io;
file = (grub_file_t) grub_zalloc (sizeof (*file));
if (!file)
return 0;

View File

@@ -69,8 +69,7 @@ grub_file_offset_close (grub_file_t file)
}
grub_file_t
grub_file_offset_open (grub_file_t parent, enum grub_file_type type,
grub_off_t start, grub_off_t size)
grub_file_offset_open (grub_file_t parent, grub_off_t start, grub_off_t size)
{
struct grub_offset_file *off_data;
grub_file_t off_file, last_off_file;
@@ -96,10 +95,10 @@ grub_file_offset_open (grub_file_t parent, enum grub_file_type type,
last_off_file = NULL;
for (filter = GRUB_FILE_FILTER_COMPRESSION_FIRST;
off_file && filter <= GRUB_FILE_FILTER_COMPRESSION_LAST; filter++)
if (grub_file_filters[filter])
if (grub_file_filters_enabled[filter])
{
last_off_file = off_file;
off_file = grub_file_filters[filter] (off_file, type);
off_file = grub_file_filters_enabled[filter] (off_file, parent->name);
}
if (!off_file)

View File

@@ -169,14 +169,12 @@ ERROR:
}
static grub_file_t
grub_xzio_open (grub_file_t io, enum grub_file_type type)
grub_xzio_open (grub_file_t io,
const char *name __attribute__ ((unused)))
{
grub_file_t file;
grub_xzio_t xzio;
if (type & GRUB_FILE_TYPE_NO_DECOMPRESS)
return io;
file = (grub_file_t) grub_zalloc (sizeof (*file));
if (!file)
return 0;

View File

@@ -25,45 +25,113 @@
#include <grub/i18n.h>
#include <grub/arm/reloc.h>
struct trampoline_arm
{
#define ARM_LOAD_IP 0xe59fc000
#define ARM_BX 0xe12fff1c
#define ARM_MOV_PC 0xe1a0f00c
grub_uint32_t load_ip; /* ldr ip, [pc] */
grub_uint32_t bx; /* bx ip or mov pc, ip*/
grub_uint32_t addr;
};
static grub_uint16_t thumb_template[8] =
{
0x468c, /* mov ip, r1 */
0x4903, /* ldr r1, [pc, #12] ; (10 <.text+0x10>) */
/* Exchange R1 and IP in limited Thumb instruction set.
IP gets negated but we compensate it by C code. */
/* R1 IP */
/* -A R1 */
0x4461, /* add r1, ip */ /* R1-A R1 */
0x4249, /* negs r1, r1 */ /* A-R1 R1 */
0x448c, /* add ip, r1 */ /* A-R1 A */
0x4249, /* negs r1, r1 */ /* R1-A A */
0x4461, /* add r1, ip */ /* R1 A */
0x4760 /* bx ip */
};
struct trampoline_thumb
{
grub_uint16_t template[8];
grub_uint32_t neg_addr;
};
#pragma GCC diagnostic ignored "-Wcast-align"
grub_err_t
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
const Elf_Ehdr *e = ehdr;
const Elf_Shdr *s;
unsigned i;
*tramp = 0;
*got = 0;
for (i = 0, s = (const Elf_Shdr *) ((grub_addr_t) e + e->e_shoff);
i < e->e_shnum;
i++, s = (const Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
const Elf_Rel *rel, *max;
for (rel = (const Elf_Rel *) ((grub_addr_t) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
switch (ELF_R_TYPE (rel->r_info))
{
case R_ARM_CALL:
case R_ARM_JUMP24:
{
*tramp += sizeof (struct trampoline_arm);
break;
}
case R_ARM_THM_CALL:
case R_ARM_THM_JUMP24:
case R_ARM_THM_JUMP19:
{
*tramp += sizeof (struct trampoline_thumb);
break;
}
}
}
grub_dprintf ("dl", "trampoline size %x\n", *tramp);
return GRUB_ERR_NONE;
}
/*************************************************
* Runtime dynamic linker with helper functions. *
*************************************************/
static grub_err_t
do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod)
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
grub_dl_segment_t seg;
Elf_Rel *rel;
Elf_Sym *sym;
int i, entnum;
Elf_Rel *rel, *max;
entnum = relhdr->sh_size / sizeof (Elf_Rel);
/* Find the target segment for this relocation section. */
for (seg = mod->segment ; seg ; seg = seg->next)
if (seg->section == relhdr->sh_info)
break;
if (!seg)
return grub_error (GRUB_ERR_EOF, N_("relocation segment not found"));
rel = (Elf_Rel *) ((grub_addr_t) e + relhdr->sh_offset);
/* Step through all relocations */
for (i = 0, sym = mod->symtab; i < entnum; i++)
for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
max = (Elf_Rel *) ((char *) rel + s->sh_size);
rel < max;
rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
{
Elf_Addr *target, sym_addr;
int relsym, reltype;
grub_err_t retval;
Elf_Sym *sym;
if (seg->size < rel[i].r_offset)
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
relsym = ELF_R_SYM (rel[i].r_info);
reltype = ELF_R_TYPE (rel[i].r_info);
target = (void *) ((grub_addr_t) seg->addr + rel[i].r_offset);
target = (void *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ mod->symsize * ELF_R_SYM (rel->r_info));
sym_addr = sym[relsym].st_value;
sym_addr = sym->st_value;
switch (reltype)
switch (ELF_R_TYPE (rel->r_info))
{
case R_ARM_ABS32:
{
@@ -76,16 +144,58 @@ do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod)
case R_ARM_CALL:
case R_ARM_JUMP24:
{
retval = grub_arm_reloc_jump24 (target, sym_addr);
if (retval != GRUB_ERR_NONE)
return retval;
grub_int32_t offset;
sym_addr += grub_arm_jump24_get_offset (target);
offset = sym_addr - (grub_uint32_t) target;
if ((sym_addr & 1) || !grub_arm_jump24_check_offset (offset))
{
struct trampoline_arm *tp = mod->trampptr;
mod->trampptr = tp + 1;
tp->load_ip = ARM_LOAD_IP;
tp->bx = (sym_addr & 1) ? ARM_BX : ARM_MOV_PC;
tp->addr = sym_addr + 8;
offset = (grub_uint8_t *) tp - (grub_uint8_t *) target - 8;
}
if (!grub_arm_jump24_check_offset (offset))
return grub_error (GRUB_ERR_BAD_MODULE,
"trampoline out of range");
grub_arm_jump24_set_offset (target, offset);
}
break;
case R_ARM_THM_CALL:
case R_ARM_THM_JUMP24:
{
/* Thumb instructions can be 16-bit aligned */
retval = grub_arm_reloc_thm_call ((grub_uint16_t *) target, sym_addr);
grub_int32_t offset;
sym_addr += grub_arm_thm_call_get_offset ((grub_uint16_t *) target);
grub_dprintf ("dl", " sym_addr = 0x%08x\n", sym_addr);
offset = sym_addr - (grub_uint32_t) target;
grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n",
target, sym_addr, offset);
if (!(sym_addr & 1) || (offset < -0x200000 || offset >= 0x200000))
{
struct trampoline_thumb *tp = mod->trampptr;
mod->trampptr = tp + 1;
grub_memcpy (tp->template, thumb_template, sizeof (tp->template));
tp->neg_addr = -sym_addr - 4;
offset = ((grub_uint8_t *) tp - (grub_uint8_t *) target - 4) | 1;
}
if (offset < -0x200000 || offset >= 0x200000)
return grub_error (GRUB_ERR_BAD_MODULE,
"trampoline out of range");
grub_dprintf ("dl", " relative destination = %p\n",
(char *) target + offset);
retval = grub_arm_thm_call_set_offset ((grub_uint16_t *) target, offset);
if (retval != GRUB_ERR_NONE)
return retval;
}
@@ -98,15 +208,37 @@ do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod)
case R_ARM_THM_JUMP19:
{
/* Thumb instructions can be 16-bit aligned */
retval = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
if (retval != GRUB_ERR_NONE)
return retval;
grub_int32_t offset;
if (!(sym_addr & 1))
return grub_error (GRUB_ERR_BAD_MODULE,
N_("Relocation targeting wrong execution state"));
sym_addr += grub_arm_thm_jump19_get_offset ((grub_uint16_t *) target);
offset = sym_addr - (grub_uint32_t) target;
if (!grub_arm_thm_jump19_check_offset (offset)
|| !(sym_addr & 1))
{
struct trampoline_thumb *tp = mod->gotptr;
mod->gotptr = tp + 1;
grub_memcpy (tp->template, thumb_template, sizeof (tp->template));
tp->neg_addr = -sym_addr - 4;
offset = ((grub_uint8_t *) tp - (grub_uint8_t *) target - 4) | 1;
}
if (!grub_arm_thm_jump19_check_offset (offset))
return grub_error (GRUB_ERR_BAD_MODULE,
"trampoline out of range");
grub_arm_thm_jump19_set_offset ((grub_uint16_t *) target, offset);
}
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
reltype);
ELF_R_TYPE (rel->r_info));
}
}
@@ -130,77 +262,3 @@ grub_arch_dl_check_header (void *ehdr)
return GRUB_ERR_NONE;
}
/*
* Verify that provided ELF header contains reference to a symbol table
*/
static int
has_symtab (Elf_Ehdr * e)
{
int i;
Elf_Shdr *s;
for (i = 0, s = (Elf_Shdr *) ((grub_uint32_t) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((grub_uint32_t) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
return 1;
return 0;
}
/*
* grub_arch_dl_relocate_symbols():
* Only externally visible function in this file.
* Locates the relocations section of the ELF object, and calls
* do_relocations() to deal with it.
*/
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
unsigned i;
if (!has_symtab (e))
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
#define FIRST_SHDR(x) ((Elf_Shdr *) ((grub_addr_t)(x) + (x)->e_shoff))
#define NEXT_SHDR(x, y) ((Elf_Shdr *) ((grub_addr_t)(y) + (x)->e_shentsize))
for (i = 0, s = FIRST_SHDR (e); i < e->e_shnum; i++, s = NEXT_SHDR (e, s))
{
grub_err_t ret;
switch (s->sh_type)
{
case SHT_REL:
{
/* Relocations, no addends */
ret = do_relocations (s, e, mod);
if (ret != GRUB_ERR_NONE)
return ret;
}
break;
case SHT_NULL:
case SHT_PROGBITS:
case SHT_SYMTAB:
case SHT_STRTAB:
case SHT_NOBITS:
case SHT_ARM_ATTRIBUTES:
break;
case SHT_RELA:
default:
{
grub_dprintf ("dl", "unhandled section_type: %d (0x%08x)\n",
s->sh_type, s->sh_type);
return GRUB_ERR_NOT_IMPLEMENTED_YET;
};
}
}
#undef FIRST_SHDR
#undef NEXT_SHDR
return GRUB_ERR_NONE;
}

View File

@@ -38,8 +38,6 @@ grub_arm_reloc_abs32 (Elf32_Word *target, Elf32_Addr sym_addr)
tmp = grub_le_to_cpu32 (*target);
tmp += sym_addr;
*target = grub_cpu_to_le32 (tmp);
grub_dprintf ("dl", " %s: reloc_abs32 0x%08x => 0x%08x", __FUNCTION__,
(unsigned int) sym_addr, (unsigned int) tmp);
return GRUB_ERR_NONE;
}
@@ -51,37 +49,16 @@ grub_arm_reloc_abs32 (Elf32_Word *target, Elf32_Addr sym_addr)
* little-endian, requiring some additional fiddling. *
********************************************************************/
/*
* R_ARM_THM_CALL/THM_JUMP24
*
* Relocate Thumb (T32) instruction set relative branches:
* B.W, BL and BLX
*/
grub_err_t
grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
grub_int32_t
grub_arm_thm_call_get_offset (grub_uint16_t *target)
{
grub_int32_t offset, offset_low, offset_high;
grub_uint32_t sign, j1, j2, is_blx;
grub_uint32_t insword, insmask;
grub_uint32_t sign, j1, j2;
grub_uint32_t insword;
grub_int32_t offset;
/* Extract instruction word in alignment-safe manner */
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
insmask = 0xf800d000;
/* B.W/BL or BLX? Affects range and expected target state */
if (((insword >> 12) & 0xd) == 0xc)
is_blx = 1;
else
is_blx = 0;
/* If BLX, target symbol must be ARM (target address LSB == 0) */
if (is_blx && (sym_addr & 1))
return grub_error (GRUB_ERR_BAD_MODULE,
N_("Relocation targeting wrong execution state"));
offset_low = -16777216;
offset_high = is_blx ? 16777212 : 16777214;
/* Extract bitfields from instruction words */
sign = (insword >> 26) & 1;
@@ -95,22 +72,32 @@ grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
if (offset & (1 << 24))
offset -= (1 << 25);
grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr);
return offset;
}
offset += sym_addr;
#ifndef GRUB_UTIL
offset -= (grub_uint32_t) target;
#endif
grub_err_t
grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset)
{
grub_uint32_t sign, j1, j2;
const grub_uint32_t insmask = 0xf800d000;
grub_uint32_t insword;
int is_blx;
grub_dprintf("dl", " %s: target=%p, sym_addr=0x%08x, offset=%d\n",
is_blx ? "BLX" : "BL", target, sym_addr, offset);
/* Extract instruction word in alignment-safe manner */
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
if ((offset < offset_low) || (offset > offset_high))
return grub_error (GRUB_ERR_BAD_MODULE,
N_("THM_CALL Relocation out of range."));
if (((insword >> 12) & 0xd) == 0xc)
is_blx = 1;
else
is_blx = 0;
grub_dprintf ("dl", " relative destination = %p",
(char *) target + offset);
if (!is_blx && !(offset & 1))
return grub_error (GRUB_ERR_BAD_MODULE, "bl/b.w targettting ARM");
/* Transform blx into bl if necessarry. */
if (is_blx && (offset & 1))
insword |= (1 << 12);
/* Reassemble instruction word */
sign = (offset >> 24) & 1;
@@ -130,21 +117,15 @@ grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
return GRUB_ERR_NONE;
}
/*
* R_ARM_THM_JUMP19
*
* Relocate conditional Thumb (T32) B<c>.W
*/
grub_err_t
grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr)
grub_int32_t
grub_arm_thm_jump19_get_offset (grub_uint16_t *target)
{
grub_int32_t offset;
grub_uint32_t insword, insmask;
grub_uint32_t insword;
/* Extract instruction word in alignment-safe manner */
insword = grub_le_to_cpu16 ((*target)) << 16
| grub_le_to_cpu16 (*(target + 1));
insmask = 0xfbc0d000;
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
/* Extract and sign extend offset */
offset = ((insword >> 26) & 1) << 19
@@ -156,18 +137,22 @@ grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr)
if (offset & (1 << 20))
offset -= (1 << 21);
/* Adjust and re-truncate offset */
offset += sym_addr;
#ifndef GRUB_UTIL
offset -= (grub_uint32_t) target;
#endif
if ((offset > 1048574) || (offset < -1048576))
return grub_error (GRUB_ERR_BAD_MODULE,
N_("THM_JUMP19 Relocation out of range."));
return offset;
}
void
grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset)
{
grub_uint32_t insword;
const grub_uint32_t insmask = 0xfbc0d000;
offset >>= 1;
offset &= 0xfffff;
/* Extract instruction word in alignment-safe manner */
insword = grub_le_to_cpu16 ((*target)) << 16
| grub_le_to_cpu16 (*(target + 1));
/* Reassemble instruction word and write back */
insword &= insmask;
insword |= ((offset >> 19) & 1) << 26
@@ -177,9 +162,15 @@ grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr)
| (offset & 0x7ff);
*target = grub_cpu_to_le16 (insword >> 16);
*(target + 1) = grub_cpu_to_le16 (insword & 0xffff);
return GRUB_ERR_NONE;
}
int
grub_arm_thm_jump19_check_offset (grub_int32_t offset)
{
if ((offset > 1048574) || (offset < -1048576))
return 0;
return 1;
}
/***********************************************************
@@ -188,35 +179,38 @@ grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr)
* ARM instructions are 32-bit in size and 32-bit aligned. *
***********************************************************/
/*
* R_ARM_JUMP24
*
* Relocate ARM (A32) B
*/
grub_err_t
grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
grub_int32_t
grub_arm_jump24_get_offset (grub_uint32_t *target)
{
grub_uint32_t insword;
grub_int32_t offset;
if (sym_addr & 1)
return grub_error (GRUB_ERR_BAD_MODULE,
N_("Relocation targeting wrong execution state"));
grub_uint32_t insword;
insword = grub_le_to_cpu32 (*target);
offset = (insword & 0x00ffffff) << 2;
if (offset & 0x02000000)
offset -= 0x04000000;
offset += sym_addr;
#ifndef GRUB_UTIL
offset -= (grub_uint32_t) target;
#endif
return offset;
}
int
grub_arm_jump24_check_offset (grub_int32_t offset)
{
if (offset >= 0x02000000 || offset < -0x02000000)
return 0;
return 1;
}
void
grub_arm_jump24_set_offset (grub_uint32_t *target,
grub_int32_t offset)
{
grub_uint32_t insword;
insword = grub_le_to_cpu32 (*target);
insword &= 0xff000000;
insword |= (offset >> 2) & 0x00ffffff;
*target = grub_cpu_to_le32 (insword);
return GRUB_ERR_NONE;
}

View File

@@ -0,0 +1,63 @@
/*
* 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/cache.h>
#include <grub/misc.h>
static grub_int64_t dlinesz;
static grub_int64_t ilinesz;
/* Prototypes for asm functions. */
void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end,
grub_uint64_t line_size);
void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t end,
grub_uint64_t line_size);
static void
probe_caches (void)
{
grub_uint64_t cache_type;
/* Read Cache Type Register */
asm volatile ("mrs %0, ctr_el0": "=r"(cache_type));
dlinesz = 4 << ((cache_type >> 16) & 0xf);
ilinesz = 4 << (cache_type & 0xf);
grub_dprintf("cache", "D$ line size: %lld\n", (long long) dlinesz);
grub_dprintf("cache", "I$ line size: %lld\n", (long long) ilinesz);
}
void
grub_arch_sync_caches (void *address, grub_size_t len)
{
grub_uint64_t start, end, max_align;
if (dlinesz == 0)
probe_caches();
if (dlinesz == 0)
grub_fatal ("Unknown cache line size!");
max_align = dlinesz > ilinesz ? dlinesz : ilinesz;
start = ALIGN_DOWN ((grub_uint64_t) address, max_align);
end = ALIGN_UP ((grub_uint64_t) address + len, max_align);
grub_arch_clean_dcache_range (start, end, dlinesz);
grub_arch_invalidate_icache_range (start, end, ilinesz);
}

View File

@@ -0,0 +1,55 @@
/*
* 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/symbol.h>
.file "cache_flush.S"
.text
/*
* Simple cache maintenance functions
*/
// x0 - *beg (inclusive)
// x1 - *end (exclusive)
// x2 - line size
FUNCTION(grub_arch_clean_dcache_range)
// Clean data cache for range to point-of-unification
1: cmp x0, x1
b.ge 2f
dc cvau, x0 // Clean Virtual Address to PoU
add x0, x0, x2 // Next line
b 1b
2: dsb ish
isb
ret
// x0 - *beg (inclusive)
// x1 - *end (exclusive)
// x2 - line size
FUNCTION(grub_arch_invalidate_icache_range)
// Invalidate instruction cache for range to point-of-unification
1: cmp x0, x1
b.ge 2f
ic ivau, x0 // Invalidate Virtual Address to PoU
add x0, x0, x2 // Next line
b 1b
// Branch predictor invalidation not needed on AArch64
2: dsb ish
isb
ret

165
grub-core/kern/arm64/dl.c Normal file
View File

@@ -0,0 +1,165 @@
/* dl.c - arch-dependent part of loadable module support */
/*
* 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/dl.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/mm.h>
#include <grub/i18n.h>
#include <grub/cpu/reloc.h>
struct trampoline
{
#define LDR 0x58000050
#define BR 0xd61f0200
grub_uint32_t ldr; /* ldr x16, 8 */
grub_uint32_t br; /* br x16 */
grub_uint64_t addr;
};
/*
* Check if EHDR is a valid ELF header.
*/
grub_err_t
grub_arch_dl_check_header (void *ehdr)
{
Elf_Ehdr *e = ehdr;
/* Check the magic numbers. */
if (e->e_ident[EI_CLASS] != ELFCLASS64
|| e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_AARCH64)
return grub_error (GRUB_ERR_BAD_OS,
N_("invalid arch-dependent ELF magic"));
return GRUB_ERR_NONE;
}
#pragma GCC diagnostic ignored "-Wcast-align"
grub_err_t
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
const Elf_Ehdr *e = ehdr;
const Elf_Shdr *s;
unsigned i;
*tramp = 0;
*got = 0;
for (i = 0, s = (const Elf_Shdr *) ((grub_addr_t) e + e->e_shoff);
i < e->e_shnum;
i++, s = (const Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize))
if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
{
const Elf_Rel *rel, *max;
for (rel = (const Elf_Rel *) ((grub_addr_t) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel = (const Elf_Rel *) ((grub_addr_t) rel + s->sh_entsize))
switch (ELF_R_TYPE (rel->r_info))
{
case R_AARCH64_CALL26:
case R_AARCH64_JUMP26:
{
*tramp += sizeof (struct trampoline);
break;
}
}
}
return GRUB_ERR_NONE;
}
/*
* Unified function for both REL and RELA
*/
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
max = (Elf_Rel *) ((char *) rel + s->sh_size);
rel < max;
rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
{
Elf_Sym *sym;
void *place;
grub_uint64_t sym_addr;
if (rel->r_offset >= seg->size)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
sym = (Elf_Sym *) ((char *) mod->symtab
+ mod->symsize * ELF_R_SYM (rel->r_info));
sym_addr = sym->st_value;
if (s->sh_type == SHT_RELA)
sym_addr += ((Elf_Rela *) rel)->r_addend;
place = (void *) ((grub_addr_t) seg->addr + rel->r_offset);
switch (ELF_R_TYPE (rel->r_info))
{
case R_AARCH64_ABS64:
{
grub_uint64_t *abs_place = place;
grub_dprintf ("dl", " reloc_abs64 %p => 0x%016llx\n",
place, (unsigned long long) sym_addr);
*abs_place = (grub_uint64_t) sym_addr;
}
break;
case R_AARCH64_CALL26:
case R_AARCH64_JUMP26:
{
grub_int64_t offset = sym_addr - (grub_uint64_t) place;
if (!grub_arm_64_check_xxxx26_offset (offset))
{
struct trampoline *tp = mod->trampptr;
mod->trampptr = tp + 1;
tp->ldr = LDR;
tp->br = BR;
tp->addr = sym_addr;
offset = (grub_uint8_t *) tp - (grub_uint8_t *) place;
}
if (!grub_arm_64_check_xxxx26_offset (offset))
return grub_error (GRUB_ERR_BAD_MODULE,
N_("Trampoline out of range"));
grub_arm64_set_xxxx26_offset (place, offset);
}
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
return GRUB_ERR_NONE;
}

View File

@@ -0,0 +1,55 @@
/* dl_helper.c - relocation helper functions for modules and grub-mkimage */
/*
* 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/dl.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/mm.h>
#include <grub/i18n.h>
#include <grub/arm64/reloc.h>
/*
* grub_arm64_reloc_xxxx26():
*
* JUMP26/CALL26 relocations for B and BL instructions.
*/
int
grub_arm_64_check_xxxx26_offset (grub_int64_t offset)
{
const grub_ssize_t offset_low = -(1 << 27), offset_high = (1 << 27) - 1;
if ((offset < offset_low) || (offset > offset_high))
return 0;
return 1;
}
void
grub_arm64_set_xxxx26_offset (grub_uint32_t *place, grub_int64_t offset)
{
const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfc000000);
grub_dprintf ("dl", " reloc_xxxx64 %p %c= 0x%llx\n",
place, offset > 0 ? '+' : '-',
offset < 0 ? (long long) -(unsigned long long) offset : offset);
*place &= insmask;
*place |= grub_cpu_to_le32 (offset >> 2) & ~insmask;
}

View File

@@ -0,0 +1,39 @@
/*
* 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/symbol.h>
.file "startup.S"
.text
FUNCTION(_start)
/*
* EFI_SYSTEM_TABLE and EFI_HANDLE are passed in x1/x0.
*/
ldr x2, efi_image_handle_val
str x0, [x2]
ldr x2, efi_system_table_val
str x1, [x2]
ldr x2, grub_main_val
br x2
grub_main_val:
.quad EXT_C(grub_main)
efi_system_table_val:
.quad EXT_C(grub_efi_system_table)
efi_image_handle_val:
.quad EXT_C(grub_efi_image_handle)

View File

@@ -229,9 +229,10 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
unsigned i;
Elf_Shdr *s;
grub_size_t tsize = 0, talign = 1;
#if defined (__ia64__) || defined (__powerpc__)
#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__)
grub_size_t tramp;
grub_size_t got;
grub_err_t err;
#endif
char *ptr;
@@ -244,10 +245,10 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
talign = s->sh_addralign;
}
#if defined (__ia64__) || defined (__powerpc__)
grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
tramp *= GRUB_ARCH_DL_TRAMP_SIZE;
got *= sizeof (grub_uint64_t);
#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__)
err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
if (err)
return err;
tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN);
if (talign < GRUB_ARCH_DL_TRAMP_ALIGN)
talign = GRUB_ARCH_DL_TRAMP_ALIGN;
@@ -313,12 +314,14 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
mod->segment = seg;
}
}
#if defined (__ia64__) || defined (__powerpc__)
#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__)
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
mod->tramp = ptr;
mod->trampptr = ptr;
ptr += tramp;
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN);
mod->got = ptr;
mod->gotptr = ptr;
ptr += got;
#endif
@@ -351,6 +354,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
#else
mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset);
#endif
mod->symsize = s->sh_entsize;
sym = mod->symtab;
size = s->sh_size;
entsize = s->sh_entsize;
@@ -560,6 +564,37 @@ grub_dl_flush_cache (grub_dl_t mod)
grub_arch_sync_caches (mod->base, mod->sz);
}
static grub_err_t
grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
unsigned i;
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
{
grub_dl_segment_t seg;
grub_err_t err;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
if (err)
return err;
}
}
return GRUB_ERR_NONE;
}
/* Load a module from core memory. */
grub_dl_t
grub_dl_load_core_noinit (void *addr, grub_size_t size)
@@ -606,7 +641,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
|| grub_dl_resolve_dependencies (mod, e)
|| grub_dl_load_segments (mod, e)
|| grub_dl_resolve_symbols (mod, e)
|| grub_arch_dl_relocate_symbols (mod, e))
|| grub_dl_relocate_symbols (mod, e))
{
mod->fini = 0;
grub_dl_unload (mod);
@@ -653,7 +688,7 @@ grub_dl_load_file (const char *filename)
void *core = 0;
grub_dl_t mod = 0;
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE);
file = grub_file_open (filename);
if (! file)
return 0;

View File

@@ -741,12 +741,17 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
{
grub_efi_file_path_device_path_t *fp;
grub_uint8_t buf[(len - 4) * 2 + 1];
grub_uint8_t *buf;
fp = (grub_efi_file_path_device_path_t *) dp;
*grub_utf16_to_utf8 (buf, fp->path_name,
(len - 4) / sizeof (grub_efi_char16_t))
= '\0';
buf = grub_malloc ((len - 4) * 2 + 1);
if (buf)
*grub_utf16_to_utf8 (buf, fp->path_name,
(len - 4) / sizeof (grub_efi_char16_t))
= '\0';
else
grub_errno = GRUB_ERR_NONE;
grub_printf ("/File(%s)", buf);
grub_free (buf);
}
break;
case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE:

View File

@@ -32,6 +32,12 @@
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
#define PAGES_TO_BYTES(pages) ((pages) << 12)
#if defined (__code_model_large__) || !defined (__x86_64__)
#define MAX_USABLE_ADDRESS 0xffffffff
#else
#define MAX_USABLE_ADDRESS 0x7fffffff
#endif
/* The size of a memory map obtained from the firmware. This must be
a multiplier of 4KB. */
#define MEMORY_MAP_SIZE 0x3000
@@ -58,7 +64,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
#if 1
/* Limit the memory access to less than 4GB for 32-bit platforms. */
if (address > 0xffffffff)
if (address > MAX_USABLE_ADDRESS)
return 0;
#endif
@@ -66,7 +72,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
if (address == 0)
{
type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
address = 0xffffffff;
address = MAX_USABLE_ADDRESS;
}
else
type = GRUB_EFI_ALLOCATE_ADDRESS;
@@ -86,7 +92,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
{
/* Uggh, the address 0 was allocated... This is too annoying,
so reallocate another one. */
address = 0xffffffff;
address = MAX_USABLE_ADDRESS;
status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
grub_efi_free_pages (0, pages);
if (status != GRUB_EFI_SUCCESS)
@@ -319,7 +325,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
{
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
#if 1
&& desc->physical_start <= 0xffffffff
&& desc->physical_start <= MAX_USABLE_ADDRESS
#endif
&& desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
&& desc->num_pages != 0)
@@ -337,9 +343,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
#if 1
if (BYTES_TO_PAGES (filtered_desc->physical_start)
+ filtered_desc->num_pages
> BYTES_TO_PAGES (0x100000000LL))
> BYTES_TO_PAGES (MAX_USABLE_ADDRESS+1LL))
filtered_desc->num_pages
= (BYTES_TO_PAGES (0x100000000LL)
= (BYTES_TO_PAGES (MAX_USABLE_ADDRESS+1LL)
- BYTES_TO_PAGES (filtered_desc->physical_start));
#endif

View File

@@ -100,12 +100,12 @@ fail:
}
grub_elf_t
grub_elf_open (const char *name, enum grub_file_type type)
grub_elf_open (const char *name)
{
grub_file_t file;
grub_elf_t elf;
file = grub_file_open (name, type);
file = grub_file_open (name);
if (! file)
return 0;

View File

@@ -39,14 +39,17 @@ grub_arch_dl_check_header (void *ehdr)
}
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
(void) mod;
(void) ehdr;
(void) s;
(void) seg;
return GRUB_ERR_BAD_MODULE;
}
#if defined (__ia64__) || defined (__powerpc__)
#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__)
void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)),
grub_size_t *tramp, grub_size_t *got)
{

View File

@@ -39,8 +39,9 @@ is_dir (const char *path, const char *name)
{
int len1 = strlen(path);
int len2 = strlen(name);
int ret;
char pathname[len1 + 1 + len2 + 1 + 13];
char *pathname = xmalloc (len1 + 1 + len2 + 1 + 13);
strcpy (pathname, path);
/* Avoid UNC-path "//name" on Cygwin. */
@@ -49,7 +50,9 @@ is_dir (const char *path, const char *name)
strcat (pathname, name);
return grub_util_is_directory (pathname);
ret = grub_util_is_directory (pathname);
free (pathname);
return ret;
}
struct grub_hostfs_data

View File

@@ -166,6 +166,8 @@ static struct argp argp = {
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
int
main (int argc, char *argv[])
{

View File

@@ -28,7 +28,8 @@
void (*EXPORT_VAR (grub_grubnet_fini)) (void);
grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX];
grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX];
grub_file_filter_t grub_file_filters_enabled[GRUB_FILE_FILTER_MAX];
/* Get the device part of the filename NAME. It is enclosed by parentheses. */
char *
@@ -58,7 +59,7 @@ grub_file_get_device_name (const char *name)
}
grub_file_t
grub_file_open (const char *name, enum grub_file_type type)
grub_file_open (const char *name)
{
grub_device_t device = 0;
grub_file_t file = 0, last_file = 0;
@@ -104,20 +105,18 @@ grub_file_open (const char *name, enum grub_file_type type)
file->name = grub_strdup (name);
grub_errno = GRUB_ERR_NONE;
for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters);
for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters_enabled);
filter++)
if (grub_file_filters[filter])
if (grub_file_filters_enabled[filter])
{
last_file = file;
file = grub_file_filters[filter] (file, type);
if (file && file != last_file)
{
file->name = grub_strdup (name);
grub_errno = GRUB_ERR_NONE;
}
file = grub_file_filters_enabled[filter] (file, name);
}
if (!file)
grub_file_close (last_file);
grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
sizeof (grub_file_filters_enabled));
return file;
@@ -129,6 +128,9 @@ grub_file_open (const char *name, enum grub_file_type type)
grub_free (file);
grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
sizeof (grub_file_filters_enabled));
return 0;
}

View File

@@ -17,8 +17,6 @@
*/
#include <grub/symbol.h>
/* For stack parameters. */
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
#include <grub/cpu/linux.h>
#include <grub/offsets.h>

View File

@@ -40,75 +40,42 @@ grub_arch_dl_check_header (void *ehdr)
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
Elf_Rel *rel, *max;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
max = (Elf_Rel *) ((char *) rel + s->sh_size);
rel < max;
rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
{
Elf_Word *addr;
Elf_Sym *sym;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
entsize = s->sh_entsize;
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ mod->symsize * ELF_R_SYM (rel->r_info));
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
grub_dl_segment_t seg;
switch (ELF_R_TYPE (rel->r_info))
{
case R_386_32:
*addr += sym->st_value;
break;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
{
Elf_Word *addr;
Elf_Sym *sym;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
switch (ELF_R_TYPE (rel->r_info))
{
case R_386_32:
*addr += sym->st_value;
break;
case R_386_PC32:
*addr += (sym->st_value - (Elf_Word) seg->addr
- rel->r_offset);
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
}
}
case R_386_PC32:
*addr += (sym->st_value - (grub_addr_t) addr);
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
return GRUB_ERR_NONE;
}

View File

@@ -161,13 +161,13 @@ mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size,
void *data __attribute__ ((unused)))
{
/* Avoid the lower memory. */
if (addr < 0x100000)
if (addr < GRUB_MEMORY_MACHINE_UPPER_START)
{
if (size <= 0x100000 - addr)
if (size <= GRUB_MEMORY_MACHINE_UPPER_START - addr)
return 0;
size -= 0x100000 - addr;
addr = 0x100000;
size -= GRUB_MEMORY_MACHINE_UPPER_START - addr;
addr = GRUB_MEMORY_MACHINE_UPPER_START;
}
/* Ignore >4GB. */

View File

@@ -96,17 +96,8 @@ struct iterator_ctx
grub_size_t nresources;
};
static int
count_cards (grub_pci_device_t dev __attribute__ ((unused)),
grub_pci_id_t pciid __attribute__ ((unused)),
void *data)
{
int *cnt = data;
(*cnt)++;
return 0;
}
/* We don't support bridges, so can't have more than 32 devices. */
#define MAX_DEVICES 32
static int
find_resources (grub_pci_device_t dev,
@@ -116,6 +107,9 @@ find_resources (grub_pci_device_t dev,
struct iterator_ctx *ctx = data;
int bar;
if (ctx->nresources >= MAX_DEVICES * 6)
return 1;
for (bar = 0; bar < 6; bar++)
{
grub_pci_address_t addr;
@@ -190,13 +184,10 @@ enable_cards (grub_pci_device_t dev,
static void
grub_pci_assign_addresses (void)
{
int ncards = 0;
struct iterator_ctx ctx;
grub_pci_iterate (count_cards, &ncards);
{
struct resource resources[ncards * 6];
struct resource resources[MAX_DEVICES * 6];
int done;
unsigned i;
ctx.nresources = 0;

View File

@@ -19,7 +19,6 @@
#include <config.h>
#include <grub/symbol.h>
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
#include <grub/machine/kernel.h>

View File

@@ -16,7 +16,7 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
/*
* Note: These functions defined in this file may be called from C.
@@ -196,8 +196,6 @@ protcseg:
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/i386/pc/memory.h>
prot_to_real:
/* just in case, set GDT */
lgdt gdtdesc

View File

@@ -46,117 +46,82 @@ grub_arch_dl_check_header (void *ehdr)
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
grub_uint64_t *gp, *gpptr;
struct grub_ia64_trampoline *tr;
Elf_Rela *rel, *max;
gp = (grub_uint64_t *) mod->base;
gpptr = (grub_uint64_t *) mod->got;
tr = mod->tramp;
for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset),
max = (Elf_Rela *) ((char *) rel + s->sh_size);
rel < max;
rel = (Elf_Rela *) ((char *) rel + s->sh_entsize))
{
grub_addr_t addr;
Elf_Sym *sym;
grub_uint64_t value;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
if (seg->size < (rel->r_offset & ~3))
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
addr = (grub_addr_t) seg->addr + rel->r_offset;
sym = (Elf_Sym *) ((char *) mod->symtab
+ mod->symsize * ELF_R_SYM (rel->r_info));
entsize = s->sh_entsize;
/* On the PPC the value does not have an explicit
addend, add it. */
value = sym->st_value + rel->r_addend;
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_RELA)
{
grub_dl_segment_t seg;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
switch (ELF_R_TYPE (rel->r_info))
{
case R_IA64_PCREL21B:
{
Elf_Rela *rel, *max;
grub_uint64_t noff;
struct grub_ia64_trampoline *tr = mod->trampptr;
grub_ia64_make_trampoline (tr, value);
noff = ((char *) tr - (char *) (addr & ~3)) >> 4;
mod->trampptr = tr + 1;
for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
{
grub_addr_t addr;
Elf_Sym *sym;
grub_uint64_t value;
if (seg->size < (rel->r_offset & ~3))
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (grub_addr_t) seg->addr + rel->r_offset;
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
/* On the PPC the value does not have an explicit
addend, add it. */
value = sym->st_value + rel->r_addend;
switch (ELF_R_TYPE (rel->r_info))
{
case R_IA64_PCREL21B:
{
grub_uint64_t noff;
grub_ia64_make_trampoline (tr, value);
noff = ((char *) tr - (char *) (addr & ~3)) >> 4;
tr = (struct grub_ia64_trampoline *) ((char *) tr + GRUB_IA64_DL_TRAMP_SIZE);
if (noff & ~MASK19)
return grub_error (GRUB_ERR_BAD_OS,
"trampoline offset too big (%lx)", noff);
grub_ia64_add_value_to_slot_20b (addr, noff);
}
break;
case R_IA64_SEGREL64LSB:
*(grub_uint64_t *) addr += value - (grub_addr_t) seg->addr;
break;
case R_IA64_FPTR64LSB:
case R_IA64_DIR64LSB:
*(grub_uint64_t *) addr += value;
break;
case R_IA64_PCREL64LSB:
*(grub_uint64_t *) addr += value - addr;
break;
case R_IA64_GPREL22:
grub_ia64_add_value_to_slot_21 (addr, value - (grub_addr_t) gp);
break;
case R_IA64_LTOFF22X:
case R_IA64_LTOFF22:
if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
value = *(grub_uint64_t *) sym->st_value + rel->r_addend;
case R_IA64_LTOFF_FPTR22:
*gpptr = value;
grub_ia64_add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp);
gpptr++;
break;
/* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */
case R_IA64_LDXMOV:
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
if (noff & ~MASK19)
return grub_error (GRUB_ERR_BAD_OS,
"trampoline offset too big (%lx)", noff);
grub_ia64_add_value_to_slot_20b (addr, noff);
}
}
break;
case R_IA64_SEGREL64LSB:
*(grub_uint64_t *) addr += value - (grub_addr_t) seg->addr;
break;
case R_IA64_FPTR64LSB:
case R_IA64_DIR64LSB:
*(grub_uint64_t *) addr += value;
break;
case R_IA64_PCREL64LSB:
*(grub_uint64_t *) addr += value - addr;
break;
case R_IA64_GPREL22:
grub_ia64_add_value_to_slot_21 (addr, value - (grub_addr_t) mod->base);
break;
case R_IA64_LTOFF22X:
case R_IA64_LTOFF22:
if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
value = *(grub_uint64_t *) sym->st_value + rel->r_addend;
case R_IA64_LTOFF_FPTR22:
{
grub_uint64_t *gpptr = mod->gotptr;
*gpptr = value;
grub_ia64_add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) mod->base);
mod->gotptr = gpptr + 1;
break;
}
/* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */
case R_IA64_LDXMOV:
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
return GRUB_ERR_NONE;
}

View File

@@ -152,8 +152,6 @@ static const grub_uint8_t jump[0x20] =
void
grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr)
{
COMPILE_TIME_ASSERT (sizeof (struct grub_ia64_trampoline)
== GRUB_IA64_DL_TRAMP_SIZE);
grub_memcpy (tr->nop, nopm, sizeof (tr->nop));
tr->addr_hi[0] = ((addr & 0xc00000) >> 16);
tr->addr_hi[1] = (addr >> 24) & 0xff;
@@ -170,7 +168,7 @@ grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr)
grub_memcpy (tr->jump, jump, sizeof (tr->jump));
}
void
grub_err_t
grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
@@ -187,7 +185,7 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
break;
if (i == grub_le_to_cpu16 (e->e_shnum))
return;
return GRUB_ERR_NONE;
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff));
i < grub_le_to_cpu16 (e->e_shnum);
@@ -211,7 +209,9 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
break;
}
}
*tramp = cntt;
*got = cntg;
*tramp = cntt * sizeof (struct grub_ia64_trampoline);
*got = cntg * sizeof (grub_uint64_t);
return GRUB_ERR_NONE;
}

View File

@@ -396,8 +396,8 @@ grub_machine_get_bootlocation (char **device, char **path)
const char *syspart = 0;
if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length
>= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
>= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
&& GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable)
syspart = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("SystemPartition");
if (!syspart)

View File

@@ -20,11 +20,11 @@ FUNCTION (grub_arch_sync_dma_caches)
move $t0, $t2
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
cache_op 1, 0($t0)
#ifdef GRUB_MACHINE_MIPS_LOONGSON
cache 1, 1($t0)
cache 1, 2($t0)
cache 1, 3($t0)
cache_op 1, 1($t0)
cache_op 1, 2($t0)
cache_op 1, 3($t0)
addiu $t1, $t1, -0x20
bne $t1, $zero, 1b
@@ -34,36 +34,36 @@ FUNCTION (grub_arch_sync_dma_caches)
bne $t1, $zero, 1b
addiu $t0, $t0, 0x4
#endif
sync
sync_op
move $t0, $t2
subu $t1, $t3, $t2
2:
#ifdef GRUB_MACHINE_MIPS_LOONGSON
cache 0, 0($t0)
cache_op 0, 0($t0)
addiu $t1, $t1, -0x20
bne $t1, $zero, 2b
addiu $t0, $t0, 0x20
#else
cache 0, 0($t0)
cache_op 0, 0($t0)
addiu $t1, $t1, -4
bne $t1, $zero, 2b
addiu $t0, $t0, 0x4
#endif
sync
sync_op
move $t0, $t2
subu $t1, $t3, $t2
2:
#ifdef GRUB_MACHINE_MIPS_LOONGSON
cache 23, 0($t0)
cache_op 23, 0($t0)
addiu $t1, $t1, -0x20
bne $t1, $zero, 2b
addiu $t0, $t0, 0x20
#else
cache 23, 0($t0)
cache_op 23, 0($t0)
addiu $t1, $t1, -0x4
bne $t1, $zero, 2b
addiu $t0, $t0, 0x4
#endif
sync
sync_op
jr $ra

View File

@@ -1,3 +1,17 @@
#ifndef CACHE_OP_DEFINED
#define CACHE_OP_DEFINED 1
.macro cache_op op addr
.set mips3
cache \op, \addr
.set mips1
.endm
.macro sync_op
.set mips3
sync
.set mips1
.endm
#endif
move $t2, $a0
addu $t3, $a0, $a1
srl $t2, $t2, 5
@@ -8,12 +22,12 @@
move $t0, $t2
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
cache_op 1, 0($t0)
/* All four ways. */
#ifdef GRUB_MACHINE_MIPS_LOONGSON
cache 1, 1($t0)
cache 1, 2($t0)
cache 1, 3($t0)
cache_op 1, 1($t0)
cache_op 1, 2($t0)
cache_op 1, 3($t0)
addiu $t1, $t1, -0x20
bne $t1, $zero, 1b
addiu $t0, $t0, 0x20
@@ -23,11 +37,11 @@
bne $t1, $zero, 1b
addiu $t0, $t0, 0x4
#endif
sync
sync_op
move $t0, $t2
subu $t1, $t3, $t2
2:
cache 0, 0($t0)
cache_op 0, 0($t0)
#ifdef GRUB_MACHINE_MIPS_LOONGSON
addiu $t1, $t1, -0x20
bne $t1, $zero, 2b
@@ -37,4 +51,4 @@
bne $t1, $zero, 2b
addiu $t0, $t0, 0x4
#endif
sync
sync_op

View File

@@ -27,6 +27,7 @@
/* Dummy __gnu_local_gp. Resolved by linker. */
static char __gnu_local_gp_dummy;
static char _gp_disp_dummy;
/* Check if EHDR is a valid ELF header. */
grub_err_t
@@ -51,199 +52,210 @@ grub_arch_dl_check_header (void *ehdr)
#pragma GCC diagnostic ignored "-Wcast-align"
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
grub_size_t gp_size = 0;
const Elf_Ehdr *e = ehdr;
const Elf_Shdr *s;
/* FIXME: suboptimal. */
grub_uint32_t *gp, *gpptr;
grub_uint32_t gp0;
grub_size_t gp_size = 0;
unsigned i;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
*tramp = 0;
*got = 0;
for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
entsize = s->sh_entsize;
/* Find reginfo. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_MIPS_REGINFO)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found");
gp0 = ((grub_uint32_t *)((char *) e + s->sh_offset))[5];
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
grub_dl_segment_t seg;
const Elf_Rel *rel, *max;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_GOT16:
case R_MIPS_CALL16:
case R_MIPS_GPREL32:
gp_size += 4;
break;
}
}
for (rel = (const Elf_Rel *) ((const char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_GOT16:
case R_MIPS_CALL16:
case R_MIPS_GPREL32:
gp_size += 4;
break;
}
}
if (gp_size > 0x08000)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "__gnu_local_gp is too big\n");
gpptr = gp = grub_malloc (gp_size);
if (!gp)
return grub_errno;
*got = gp_size;
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
grub_dl_segment_t seg;
return GRUB_ERR_NONE;
}
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
grub_uint32_t gp0;
Elf_Ehdr *e = ehdr;
if (seg)
if (!mod->reginfo)
{
unsigned i;
Elf_Shdr *ri;
/* Find reginfo. */
for (i = 0, ri = (Elf_Shdr *) ((char *) ehdr + e->e_shoff);
i < e->e_shnum;
i++, ri = (Elf_Shdr *) ((char *) ri + e->e_shentsize))
if (ri->sh_type == SHT_MIPS_REGINFO)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found");
mod->reginfo = (grub_uint32_t *)((char *) ehdr + ri->sh_offset);
}
gp0 = mod->reginfo[5];
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
max = (Elf_Rel *) ((char *) rel + s->sh_size);
rel < max;
rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
{
grub_uint8_t *addr;
Elf_Sym *sym;
grub_uint32_t sym_value;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ mod->symsize * ELF_R_SYM (rel->r_info));
sym_value = sym->st_value;
if (sym_value == (grub_addr_t) &__gnu_local_gp_dummy)
sym_value = (grub_addr_t) mod->got;
else if (sym_value == (grub_addr_t) &_gp_disp_dummy)
{
sym_value = (grub_addr_t) mod->got - (grub_addr_t) addr;
if (ELF_R_TYPE (rel->r_info) == R_MIPS_LO16)
/* ABI mandates +4 even if partner lui doesn't
immediately precede addiu. */
sym_value += 4;
}
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_HI16:
{
Elf_Rel *rel, *max;
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
{
grub_uint8_t *addr;
Elf_Sym *sym;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
sym->st_value = (grub_addr_t) gp;
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_HI16:
{
grub_uint32_t value;
Elf_Rel *rel2;
grub_uint32_t value;
Elf_Rel *rel2;
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
addr += 2;
#endif
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
value = (*(grub_uint16_t *) addr << 16)
+ sym->st_value + 0x8000;
for (rel2 = rel + 1; rel2 < max; rel2++)
if (ELF_R_SYM (rel2->r_info)
== ELF_R_SYM (rel->r_info)
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
{
value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
value = (*(grub_uint16_t *) addr << 16)
+ sym_value + 0x8000;
for (rel2 = rel + 1; rel2 < max; rel2++)
if (ELF_R_SYM (rel2->r_info)
== ELF_R_SYM (rel->r_info)
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
{
value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset
#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ 2
+ 2
#endif
);
break;
}
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
}
break;
case R_MIPS_LO16:
);
break;
}
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
}
break;
case R_MIPS_LO16:
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
addr += 2;
#endif
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
break;
case R_MIPS_32:
*(grub_uint32_t *) addr += sym->st_value;
break;
case R_MIPS_GPREL32:
*(grub_uint32_t *) addr = sym->st_value
+ *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp;
break;
*(grub_uint16_t *) addr += sym_value & 0xffff;
break;
case R_MIPS_32:
*(grub_uint32_t *) addr += sym_value;
break;
case R_MIPS_GPREL32:
*(grub_uint32_t *) addr = sym_value
+ *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)mod->got;
break;
case R_MIPS_26:
{
grub_uint32_t value;
grub_uint32_t raw;
raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
value = raw << 2;
value += sym->st_value;
raw = (value >> 2) & 0x3ffffff;
case R_MIPS_26:
{
grub_uint32_t value;
grub_uint32_t raw;
raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
value = raw << 2;
value += sym_value;
raw = (value >> 2) & 0x3ffffff;
*(grub_uint32_t *) addr =
raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
}
break;
case R_MIPS_GOT16:
case R_MIPS_CALL16:
/* FIXME: reuse*/
*(grub_uint32_t *) addr =
raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
}
break;
case R_MIPS_GOT16:
if (ELF_ST_BIND (sym->st_info) == STB_LOCAL)
{
Elf_Rel *rel2;
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
sym_value += (*(grub_uint16_t *) addr << 16)
+ 0x8000;
for (rel2 = rel + 1; rel2 < max; rel2++)
if (ELF_R_SYM (rel2->r_info)
== ELF_R_SYM (rel->r_info)
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
{
sym_value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
+ 2
#endif
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
*(grub_uint16_t *) addr
= sizeof (grub_uint32_t) * (gpptr - gp);
gpptr++;
break;
case R_MIPS_JALR:
break;
default:
{
grub_free (gp);
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
);
break;
}
}
sym_value &= 0xffff0000;
*(grub_uint16_t *) addr = 0;
}
case R_MIPS_CALL16:
{
grub_uint32_t *gpptr = mod->gotptr;
/* FIXME: reuse*/
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
*gpptr = sym_value + *(grub_uint16_t *) addr;
*(grub_uint16_t *) addr
= sizeof (grub_uint32_t) * (gpptr - (grub_uint32_t *) mod->got);
mod->gotptr = gpptr + 1;
break;
}
}
case R_MIPS_JALR:
break;
default:
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
break;
}
}
return GRUB_ERR_NONE;
}
@@ -252,5 +264,6 @@ void
grub_arch_dl_init_linker (void)
{
grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0, 0);
grub_dl_register_symbol ("_gp_disp", &_gp_disp_dummy, 0, 0);
}

View File

@@ -116,10 +116,10 @@ bsscont:
bne $t3, $0, bsscont
nop
lui $t1, %hi(grub_main)
addiu $t1, %lo(grub_main)
lui $t9, %hi(grub_main)
addiu $t9, %lo(grub_main)
lui $sp, %hi(GRUB_MACHINE_MEMORY_STACK_HIGH)
jr $t1
jr $t9
addiu $sp, $sp, %lo(GRUB_MACHINE_MEMORY_STACK_HIGH)

View File

@@ -25,8 +25,39 @@
#include <grub/env.h>
#include <grub/i18n.h>
union printf_arg
{
/* Yes, type is also part of union as the moment we fill the value
we don't need to store its type anymore (when we'll need it, we'll
have format spec again. So save some space. */
enum
{
INT, LONG, LONGLONG,
UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG
} type;
long long ll;
};
struct printf_args
{
union printf_arg prealloc[32];
union printf_arg *ptr;
grub_size_t count;
};
static void
parse_printf_args (const char *fmt0, struct printf_args *args,
va_list args_in);
static int
grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args);
grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
struct printf_args *args);
static void
free_printf_args (struct printf_args *args)
{
if (args->ptr != args->prealloc)
grub_free (args->ptr);
}
static int
grub_iswordseparator (int c)
@@ -169,15 +200,16 @@ grub_real_dprintf (const char *file, const int line, const char *condition,
#define PREALLOC_SIZE 255
int
grub_vprintf (const char *fmt, va_list args)
grub_vprintf (const char *fmt, va_list ap)
{
grub_size_t s;
static char buf[PREALLOC_SIZE + 1];
char *curbuf = buf;
va_list ap2;
va_copy (ap2, args);
struct printf_args args;
s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, args);
parse_printf_args (fmt, &args, ap);
s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, &args);
if (s > PREALLOC_SIZE)
{
curbuf = grub_malloc (s + 1);
@@ -191,16 +223,16 @@ grub_vprintf (const char *fmt, va_list args)
curbuf = buf;
}
else
s = grub_vsnprintf_real (curbuf, s, fmt, ap2);
s = grub_vsnprintf_real (curbuf, s, fmt, &args);
}
va_end (ap2);
free_printf_args (&args);
grub_xputs (curbuf);
if (curbuf != buf)
grub_free (curbuf);
return s;
}
@@ -724,7 +756,7 @@ __umoddi3 (grub_uint64_t a, grub_uint64_t b)
/* Convert a long long value to a string. This function avoids 64-bit
modular arithmetic or divisions. */
static char *
static inline char *
grub_lltoa (char *str, int c, unsigned long long n)
{
unsigned base = (c == 'x') ? 16 : 10;
@@ -762,39 +794,21 @@ grub_lltoa (char *str, int c, unsigned long long n)
return p;
}
static inline void
write_char (char *str, grub_size_t *count, grub_size_t max_len, unsigned char ch)
{
if (*count < max_len)
str[*count] = ch;
(*count)++;
}
static inline void
write_str (char *str, grub_size_t *count, grub_size_t max_len, const char *s)
{
while (*s)
write_char (str, count, max_len, *s++);
}
static inline void
write_fill (char *str, grub_size_t *count, grub_size_t max_len, const char ch, int count_fill)
{
int i;
for (i = 0; i < count_fill; i++)
write_char (str, count, max_len, ch);
}
static int
grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list args_in)
static void
parse_printf_args (const char *fmt0, struct printf_args *args,
va_list args_in)
{
const char *fmt;
char c;
grub_size_t n = 0;
grub_size_t count = 0;
grub_size_t count_args = 0;
const char *fmt;
args->count = 0;
COMPILE_TIME_ASSERT (sizeof (int) == sizeof (grub_uint32_t));
COMPILE_TIME_ASSERT (sizeof (int) <= sizeof (long long));
COMPILE_TIME_ASSERT (sizeof (long) <= sizeof (long long));
COMPILE_TIME_ASSERT (sizeof (long long) == sizeof (void *)
|| sizeof (int) == sizeof (void *));
fmt = fmt0;
while ((c = *fmt++) != 0)
@@ -838,30 +852,31 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a
case 'c':
case 'C':
case 's':
count_args++;
args->count++;
break;
}
}
enum { INT, LONG, LONGLONG, POINTER } types[count_args];
union
{
int i;
long l;
long long ll;
void *p;
} args[count_args];
if (args->count <= ARRAY_SIZE (args->prealloc))
args->ptr = args->prealloc;
else
{
args->ptr = grub_malloc (args->count * sizeof (args->ptr[0]));
if (!args->ptr)
{
grub_errno = GRUB_ERR_NONE;
args->ptr = args->prealloc;
args->count = ARRAY_SIZE (args->prealloc);
}
}
COMPILE_TIME_ASSERT (sizeof (int) == sizeof (grub_uint32_t));
grub_memset (types, 0, sizeof (types));
grub_memset (args->ptr, 0, args->count * sizeof (args->ptr[0]));
fmt = fmt0;
n = 0;
while ((c = *fmt++) != 0)
{
int longfmt = 0;
int longlongfmt = 0;
grub_size_t curn;
const char *p;
@@ -901,69 +916,87 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a
{
c = *fmt++;
longfmt = 1;
if (c == 'l')
{
c = *fmt++;
longlongfmt = 1;
}
}
if (curn >= count_args)
if (c == 'l')
{
c = *fmt++;
longfmt = 2;
}
if (curn >= args->count)
continue;
switch (c)
{
case 'x':
case 'u':
args->ptr[curn].type = UNSIGNED_INT + longfmt;
break;
case 'd':
if (longlongfmt)
types[curn] = LONGLONG;
else if (longfmt)
types[curn] = LONG;
else
types[curn] = INT;
args->ptr[curn].type = INT + longfmt;
break;
case 'p':
case 's':
types[curn] = POINTER;
if (sizeof (void *) == sizeof (long long))
args->ptr[curn].type = UNSIGNED_LONGLONG;
else
args->ptr[curn].type = UNSIGNED_INT;
break;
case 'C':
case 'c':
types[curn] = INT;
args->ptr[curn].type = INT;
break;
}
}
for (n = 0; n < count_args; n++)
switch (types[n])
for (n = 0; n < args->count; n++)
switch (args->ptr[n].type)
{
case POINTER:
args[n].p = va_arg (args_in, void *);
break;
case INT:
args[n].i = va_arg (args_in, int);
args->ptr[n].ll = va_arg (args_in, int);
break;
case LONG:
args[n].l = va_arg (args_in, long);
args->ptr[n].ll = va_arg (args_in, long);
break;
case UNSIGNED_INT:
args->ptr[n].ll = va_arg (args_in, unsigned int);
break;
case UNSIGNED_LONG:
args->ptr[n].ll = va_arg (args_in, unsigned long);
break;
case LONGLONG:
args[n].ll = va_arg (args_in, long long);
case UNSIGNED_LONGLONG:
args->ptr[n].ll = va_arg (args_in, long long);
break;
}
}
static inline void __attribute__ ((always_inline))
write_char (char *str, grub_size_t *count, grub_size_t max_len, unsigned char ch)
{
if (*count < max_len)
str[*count] = ch;
(*count)++;
}
static int
grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
struct printf_args *args)
{
char c;
grub_size_t n = 0;
grub_size_t count = 0;
const char *fmt;
fmt = fmt0;
n = 0;
while ((c = *fmt++) != 0)
{
char tmp[32];
unsigned int format1 = 0;
unsigned int format2 = ~ 0U;
char zerofill = ' ';
int rightfill = 0;
int longfmt = 0;
int longlongfmt = 0;
int unsig = 0;
char rightfill = 0;
grub_size_t curn;
if (c != '%')
{
write_char (str, &count, max_len,c);
@@ -1008,15 +1041,9 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a
c = *fmt++;
if (c == 'l')
{
longfmt = 1;
c = *fmt++;
if (c == 'l')
{
longlongfmt = 1;
c = *fmt++;
}
}
c = *fmt++;
if (c == 'l')
c = *fmt++;
if (c == '%')
{
@@ -1024,45 +1051,47 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a
continue;
}
if (curn >= count_args)
if (curn >= args->count)
continue;
long long curarg = args->ptr[curn].ll;
switch (c)
{
case 'p':
write_str (str, &count, max_len, "0x");
write_char (str, &count, max_len, '0');
write_char (str, &count, max_len, 'x');
c = 'x';
longlongfmt |= (sizeof (void *) == sizeof (long long));
/* Fall through. */
case 'x':
case 'u':
unsig = 1;
/* Fall through. */
case 'd':
if (longlongfmt)
grub_lltoa (tmp, c, args[curn].ll);
else if (longfmt && unsig)
grub_lltoa (tmp, c, (unsigned long) args[curn].l);
else if (longfmt)
grub_lltoa (tmp, c, args[curn].l);
else if (unsig)
grub_lltoa (tmp, c, (unsigned) args[curn].i);
else
grub_lltoa (tmp, c, args[curn].i);
if (! rightfill && grub_strlen (tmp) < format1)
write_fill (str, &count, max_len, zerofill, format1 - grub_strlen (tmp));
write_str (str, &count, max_len, tmp);
if (rightfill && grub_strlen (tmp) < format1)
write_fill (str, &count, max_len, zerofill, format1 - grub_strlen (tmp));
{
char tmp[32];
const char *p = tmp;
grub_size_t len;
grub_size_t fill;
len = grub_lltoa (tmp, c, curarg) - tmp;
fill = len < format1 ? format1 - len : 0;
if (! rightfill)
while (fill--)
write_char (str, &count, max_len, zerofill);
while (*p)
write_char (str, &count, max_len, *p++);
if (rightfill)
while (fill--)
write_char (str, &count, max_len, zerofill);
}
break;
case 'c':
write_char (str, &count, max_len,args[curn].i & 0xff);
write_char (str, &count, max_len,curarg & 0xff);
break;
case 'C':
{
grub_uint32_t code = args[curn].i;
grub_uint32_t code = curarg;
int shift;
unsigned mask;
@@ -1103,20 +1132,25 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a
case 's':
{
grub_size_t len = 0;
const char *p = args[curn].p ? : "(null)";
grub_size_t fill;
const char *p = ((char *) (grub_addr_t) curarg) ? : "(null)";
grub_size_t i;
while (len < format2 && p[len])
len++;
if (!rightfill && len < format1)
write_fill (str, &count, max_len, zerofill, format1 - len);
fill = len < format1 ? format1 - len : 0;
if (!rightfill)
while (fill--)
write_char (str, &count, max_len, zerofill);
grub_size_t i;
for (i = 0; i < len; i++)
write_char (str, &count, max_len,*p++);
if (rightfill && len < format1)
write_fill (str, &count, max_len, zerofill, format1 - len);
if (rightfill)
while (fill--)
write_char (str, &count, max_len, zerofill);
}
break;
@@ -1131,7 +1165,6 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a
str[count] = '\0';
else
str[max_len] = '\0';
return count;
}
@@ -1139,13 +1172,18 @@ int
grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
{
grub_size_t ret;
struct printf_args args;
if (!n)
return 0;
n--;
ret = grub_vsnprintf_real (str, n, fmt, ap);
parse_printf_args (fmt, &args, ap);
ret = grub_vsnprintf_real (str, n, fmt, &args);
free_printf_args (&args);
return ret < n ? ret : n;
}
@@ -1168,22 +1206,26 @@ grub_xvasprintf (const char *fmt, va_list ap)
{
grub_size_t s, as = PREALLOC_SIZE;
char *ret;
struct printf_args args;
parse_printf_args (fmt, &args, ap);
while (1)
{
va_list ap2;
ret = grub_malloc (as + 1);
if (!ret)
return NULL;
{
free_printf_args (&args);
return NULL;
}
va_copy (ap2, ap);
s = grub_vsnprintf_real (ret, as, fmt, ap2);
va_end (ap2);
s = grub_vsnprintf_real (ret, as, fmt, &args);
if (s <= as)
return ret;
{
free_printf_args (&args);
return ret;
}
grub_free (ret);
as = s;
@@ -1220,6 +1262,15 @@ grub_abort (void)
grub_exit ();
}
#if defined (__clang__) && !defined (GRUB_UTIL)
/* clang emits references to abort(). */
void __attribute__ ((noreturn))
abort (void)
{
grub_abort ();
}
#endif
void
grub_fatal (const char *fmt, ...)
{

View File

@@ -38,9 +38,26 @@ grub_arch_dl_check_header (void *ehdr)
return GRUB_ERR_NONE;
}
/* For low-endian reverse lis and addr_high as well as ori and addr_low. */
struct trampoline
{
grub_uint32_t lis;
grub_uint32_t ori;
grub_uint32_t mtctr;
grub_uint32_t bctr;
};
static const struct trampoline trampoline_template =
{
0x3d800000,
0x618c0000,
0x7d8903a6,
0x4e800420,
};
#pragma GCC diagnostic ignored "-Wcast-align"
void
grub_err_t
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
@@ -59,7 +76,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
break;
if (i == e->e_shnum)
return;
return GRUB_ERR_NONE;
for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
i < e->e_shnum;
@@ -77,133 +94,84 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
}
return;
}
/* For low-endian reverse lis and addr_high as well as ori and addr_low. */
struct trampoline
{
grub_uint32_t lis;
grub_uint32_t ori;
grub_uint32_t mtctr;
grub_uint32_t bctr;
};
static const struct trampoline trampoline_template =
{
0x3d800000,
0x618c0000,
0x7d8903a6,
0x4e800420,
};
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
struct trampoline *tptr = mod->tramp;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
entsize = s->sh_entsize;
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_RELA)
{
grub_dl_segment_t seg;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rela *rel, *max;
for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
{
Elf_Word *addr;
Elf_Sym *sym;
grub_uint32_t value;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
/* On the PPC the value does not have an explicit
addend, add it. */
value = sym->st_value + rel->r_addend;
switch (ELF_R_TYPE (rel->r_info))
{
case GRUB_ELF_R_PPC_ADDR16_LO:
*(Elf_Half *) addr = value;
break;
case GRUB_ELF_R_PPC_REL24:
{
Elf_Sword delta = value - (Elf_Word) addr;
if (delta << 6 >> 6 != delta)
{
COMPILE_TIME_ASSERT (sizeof (struct trampoline)
== GRUB_ARCH_DL_TRAMP_SIZE);
grub_memcpy (tptr, &trampoline_template,
sizeof (*tptr));
delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr;
tptr->lis |= (((value) >> 16) & 0xffff);
tptr->ori |= ((value) & 0xffff);
tptr++;
}
if (delta << 6 >> 6 != delta)
return grub_error (GRUB_ERR_BAD_MODULE,
"relocation overflow");
*addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
break;
}
case GRUB_ELF_R_PPC_ADDR16_HA:
*(Elf_Half *) addr = (value + 0x8000) >> 16;
break;
case GRUB_ELF_R_PPC_ADDR32:
*addr = value;
break;
case GRUB_ELF_R_PPC_REL32:
*addr = value - (Elf_Word) addr;
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
}
}
*tramp *= sizeof (struct trampoline);
return GRUB_ERR_NONE;
}
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
Elf_Rela *rel, *max;
for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset),
max = (Elf_Rela *) ((char *) rel + s->sh_size);
rel < max;
rel = (Elf_Rela *) ((char *) rel + s->sh_entsize))
{
Elf_Word *addr;
Elf_Sym *sym;
grub_uint32_t value;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ mod->symsize * ELF_R_SYM (rel->r_info));
/* On the PPC the value does not have an explicit
addend, add it. */
value = sym->st_value + rel->r_addend;
switch (ELF_R_TYPE (rel->r_info))
{
case GRUB_ELF_R_PPC_ADDR16_LO:
*(Elf_Half *) addr = value;
break;
case GRUB_ELF_R_PPC_REL24:
{
Elf_Sword delta = value - (Elf_Word) addr;
if (delta << 6 >> 6 != delta)
{
struct trampoline *tptr = mod->trampptr;
grub_memcpy (tptr, &trampoline_template,
sizeof (*tptr));
delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr;
tptr->lis |= (((value) >> 16) & 0xffff);
tptr->ori |= ((value) & 0xffff);
mod->trampptr = tptr + 1;
}
if (delta << 6 >> 6 != delta)
return grub_error (GRUB_ERR_BAD_MODULE,
"relocation overflow");
*addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
break;
}
case GRUB_ELF_R_PPC_ADDR16_HA:
*(Elf_Half *) addr = (value + 0x8000) >> 16;
break;
case GRUB_ELF_R_PPC_ADDR32:
*addr = value;
break;
case GRUB_ELF_R_PPC_REL32:
*addr = value - (Elf_Word) addr;
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
return GRUB_ERR_NONE;
}

View File

@@ -42,106 +42,74 @@ grub_arch_dl_check_header (void *ehdr)
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
Elf_Rela *rel, *max;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset),
max = (Elf_Rela *) ((char *) rel + s->sh_size);
rel < max;
rel = (Elf_Rela *) ((char *) rel + s->sh_entsize))
{
Elf_Word *addr;
Elf_Sym *sym;
Elf_Addr value;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
entsize = s->sh_entsize;
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ mod->symsize * ELF_R_SYM (rel->r_info));
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_RELA)
{
grub_dl_segment_t seg;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rela *rel, *max;
for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
{
Elf_Word *addr;
Elf_Sym *sym;
Elf_Addr value;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
value = sym->st_value + rel->r_addend;
switch (ELF_R_TYPE (rel->r_info) & 0xff)
{
case R_SPARC_32: /* 3 V-word32 */
if (value & 0xFFFFFFFF00000000)
return grub_error (GRUB_ERR_BAD_MODULE,
"address out of 32 bits range");
*addr = value;
break;
case R_SPARC_WDISP30: /* 7 V-disp30 */
if (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) &&
(((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000)
!= 0xFFFFFFFF00000000))
return grub_error (GRUB_ERR_BAD_MODULE,
"displacement out of 30 bits range");
*addr = (*addr & 0xC0000000) |
(((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) &
0x3FFFFFFF);
break;
case R_SPARC_HH22: /* 9 V-imm22 */
*addr = (*addr & 0xFFC00000) | ((value >> 42) & 0x3FFFFF);
break;
case R_SPARC_HM10: /* 12 T-simm13 */
*addr = (*addr & 0xFFFFFC00) | ((value >> 32) & 0x3FF);
break;
case R_SPARC_HI22: /* 9 V-imm22 */
*addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF);
break;
case R_SPARC_LO10: /* 12 T-simm13 */
*addr = (*addr & 0xFFFFFC00) | (value & 0x3FF);
break;
case R_SPARC_64: /* 32 V-xwords64 */
*(Elf_Xword *) addr = value;
break;
case R_SPARC_OLO10:
*addr = (*addr & ~0x1fff)
| (((value & 0x3ff) +
(ELF_R_TYPE (rel->r_info) >> 8))
& 0x1fff);
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
}
}
value = sym->st_value + rel->r_addend;
switch (ELF_R_TYPE (rel->r_info) & 0xff)
{
case R_SPARC_32: /* 3 V-word32 */
if (value & 0xFFFFFFFF00000000)
return grub_error (GRUB_ERR_BAD_MODULE,
"address out of 32 bits range");
*addr = value;
break;
case R_SPARC_WDISP30: /* 7 V-disp30 */
if (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) &&
(((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000)
!= 0xFFFFFFFF00000000))
return grub_error (GRUB_ERR_BAD_MODULE,
"displacement out of 30 bits range");
*addr = (*addr & 0xC0000000) |
(((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) &
0x3FFFFFFF);
break;
case R_SPARC_HH22: /* 9 V-imm22 */
*addr = (*addr & 0xFFC00000) | ((value >> 42) & 0x3FFFFF);
break;
case R_SPARC_HM10: /* 12 T-simm13 */
*addr = (*addr & 0xFFFFFC00) | ((value >> 32) & 0x3FF);
break;
case R_SPARC_HI22: /* 9 V-imm22 */
*addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF);
break;
case R_SPARC_LO10: /* 12 T-simm13 */
*addr = (*addr & 0xFFFFFC00) | (value & 0x3FF);
break;
case R_SPARC_64: /* 32 V-xwords64 */
*(Elf_Xword *) addr = value;
break;
case R_SPARC_OLO10:
*addr = (*addr & ~0x1fff)
| (((value & 0x3ff) +
(ELF_R_TYPE (rel->r_info) >> 8))
& 0x1fff);
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
return GRUB_ERR_NONE;
}

View File

@@ -36,10 +36,14 @@ codestart:
/* Copy the modules past the end of the kernel image.
* They are currently sitting in the BSS.
*/
sethi %hi(__bss_start), %o2
or %o2, %lo(__bss_start), %o2
sethi %hi(_end), %o3
or %o3, %lo(_end), %o3
sethi %hi(__bss_start + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o2
or %o2, %lo(__bss_start + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o2
srl %o2, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o2
sll %o2, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o2
sethi %hi(_end + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o3
or %o3, %lo(_end + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o3
srl %o3, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o3
sll %o3, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o3
sethi %hi(grub_total_module_size), %o4
lduw [%o4 + %lo(grub_total_module_size)], %o4
@@ -67,16 +71,34 @@ codestart:
/* Now it's safe to clear out the BSS. */
sethi %hi(__bss_start), %o2
or %o2, %lo(__bss_start), %o2
sethi %hi(_end), %o3
or %o3, %lo(_end), %o3
1: stb %g0, [%o2]
add %o2, 1, %o2
and %o2, 7, %o3
brnz %o3, 1b
nop
sethi %hi(_end - 1), %o3
or %o3, %lo(_end - 1), %o3
srl %o3, 3, %o3
sll %o3, 3, %o3
1: stx %g0, [%o2]
add %o2, 8, %o2
cmp %o2, %o3
blt,pt %xcc, 1b
nop
sethi %hi(_end), %o3
or %o3, %lo(_end), %o3
1: stb %g0, [%o2]
add %o2, 1, %o2
cmp %o2, %o3
blt,pt %xcc, 1b
nop
sethi %hi(grub_ieee1275_original_stack), %o2
stx %o1, [%o2 + %lo(grub_ieee1275_original_stack)]
sethi %hi(grub_ieee1275_entry_fn), %o2
call grub_main
stx %o0, [%o2 + %lo(grub_ieee1275_entry_fn)]
1: ba,a 1b
nop

View File

@@ -61,7 +61,13 @@ grub_uboot_get_boot_data (void)
static grub_uint64_t
uboot_timer_ms (void)
{
return (grub_uint64_t) grub_uboot_get_timer (timer_start) / 1000;
static grub_uint32_t last = 0, high = 0;
grub_uint32_t cur = grub_uboot_get_timer (timer_start);
if (cur < last)
high++;
last = cur;
return grub_divmod64 ((((grub_uint64_t) high) << 32) | cur,
1000, 0);
}
void

View File

@@ -40,83 +40,69 @@ grub_arch_dl_check_header (void *ehdr)
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
Elf_Shdr *s, grub_dl_segment_t seg)
{
Elf64_Ehdr *e = ehdr;
Elf64_Shdr *s;
Elf64_Word entsize;
unsigned i;
Elf64_Rela *rel, *max;
/* Find a symbol table. */
for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
for (rel = (Elf64_Rela *) ((char *) ehdr + s->sh_offset),
max = (Elf64_Rela *) ((char *) rel + s->sh_size);
rel < max;
rel = (Elf64_Rela *) ((char *) rel + s->sh_entsize))
{
Elf64_Word *addr32;
Elf64_Xword *addr64;
Elf64_Sym *sym;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
entsize = s->sh_entsize;
addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset);
addr64 = (Elf64_Xword *) addr32;
sym = (Elf64_Sym *) ((char *) mod->symtab
+ mod->symsize * ELF_R_SYM (rel->r_info));
for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_RELA)
{
grub_dl_segment_t seg;
switch (ELF_R_TYPE (rel->r_info))
{
case R_X86_64_64:
*addr64 += rel->r_addend + sym->st_value;
break;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
case R_X86_64_PC32:
{
Elf64_Rela *rel, *max;
for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
{
Elf64_Word *addr32;
Elf64_Xword *addr64;
Elf64_Sym *sym;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset);
addr64 = (Elf64_Xword *) addr32;
sym = (Elf64_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
switch (ELF_R_TYPE (rel->r_info))
{
case R_X86_64_64:
*addr64 += rel->r_addend + sym->st_value;
break;
case R_X86_64_PC32:
*addr32 += rel->r_addend + sym->st_value -
(Elf64_Xword) seg->addr - rel->r_offset;
break;
case R_X86_64_32:
case R_X86_64_32S:
*addr32 += rel->r_addend + sym->st_value;
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
grub_int64_t value;
value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value -
(Elf64_Xword) seg->addr - rel->r_offset;
if (value != (grub_int32_t) value)
return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
*addr32 = value;
}
}
break;
case R_X86_64_32:
{
grub_uint64_t value = *addr32 + rel->r_addend + sym->st_value;
if (value != (grub_uint32_t) value)
return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
*addr32 = value;
}
break;
case R_X86_64_32S:
{
grub_int64_t value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value;
if (value != (grub_int32_t) value)
return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
*addr32 = value;
}
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
}
}
return GRUB_ERR_NONE;
}

View File

@@ -36,94 +36,94 @@
.text
FUNCTION(efi_wrap_0)
subq $48, %rsp
subq $40, %rsp
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_1)
subq $48, %rsp
subq $40, %rsp
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_2)
subq $48, %rsp
subq $40, %rsp
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_3)
subq $48, %rsp
subq $40, %rsp
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_4)
subq $48, %rsp
subq $40, %rsp
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_5)
subq $48, %rsp
subq $40, %rsp
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_6)
subq $64, %rsp
mov 64+8(%rsp), %rax
subq $56, %rsp
mov 56+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $64, %rsp
addq $56, %rsp
ret
FUNCTION(efi_wrap_7)
subq $96, %rsp
mov 96+16(%rsp), %rax
subq $88, %rsp
mov 88+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 96+8(%rsp), %rax
mov 88+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $96, %rsp
addq $88, %rsp
ret
FUNCTION(efi_wrap_10)
subq $96, %rsp
mov 96+40(%rsp), %rax
subq $88, %rsp
mov 88+40(%rsp), %rax
mov %rax, 72(%rsp)
mov 96+32(%rsp), %rax
mov 88+32(%rsp), %rax
mov %rax, 64(%rsp)
mov 96+24(%rsp), %rax
mov 88+24(%rsp), %rax
mov %rax, 56(%rsp)
mov 96+16(%rsp), %rax
mov 88+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 96+8(%rsp), %rax
mov 88+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $96, %rsp
addq $88, %rsp
ret

View File

@@ -341,6 +341,14 @@ page2offset (grub_uint64_t page)
return page << 12;
}
#if defined (__x86_64__) && defined (__code_model_large__)
#define MAX_TOTAL_PAGES (1LL << (64 - 12))
#elif defined (__x86_64__)
#define MAX_TOTAL_PAGES (1LL << (31 - 12))
#else
#define MAX_TOTAL_PAGES (1LL << (32 - 12))
#endif
static void
map_all_pages (void)
{
@@ -355,6 +363,9 @@ map_all_pages (void)
grub_size_t n_unusable_pages = 0;
struct mmu_update m2p_updates[2 * MAX_N_UNUSABLE_PAGES];
if (total_pages > MAX_TOTAL_PAGES - 4)
total_pages = MAX_TOTAL_PAGES - 4;
grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver));
gnttab_setver.version = 2;

View File

@@ -0,0 +1,53 @@
/*
* 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/symbol.h>
.file "setjmp.S"
.text
/*
* int grub_setjmp (grub_jmp_buf env)
*/
FUNCTION(grub_setjmp)
stp x19, x20, [x0], #16
stp x21, x22, [x0], #16
stp x23, x24, [x0], #16
stp x25, x26, [x0], #16
stp x27, x28, [x0], #16
stp x29, x30, [x0], #16
mov x1, sp
str x1, [x0]
mov x0, #0
ret
/*
* int grub_longjmp (grub_jmp_buf env, int val)
*/
FUNCTION(grub_longjmp)
ldp x19, x20, [x0], #16
ldp x21, x22, [x0], #16
ldp x23, x24, [x0], #16
ldp x25, x26, [x0], #16
ldp x27, x28, [x0], #16
ldp x29, x30, [x0], #16
ldr x2, [x0]
mov sp, x2
cmp x1, #0
csel x0, x1, x0, ne
ret

View File

@@ -125,7 +125,10 @@ void
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
grub_size_t inlen)
{
grub_uint8_t ctx[hash->contextsize];
GRUB_PROPERLY_ALIGNED_ARRAY (ctx, GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE);
if (hash->contextsize > sizeof (ctx))
grub_fatal ("Too large md context");
hash->init (&ctx);
hash->write (&ctx, in, inlen);
hash->final (&ctx);
@@ -150,27 +153,6 @@ grub_crypto_lookup_md_by_name (const char *name)
}
}
const gcry_md_spec_t *
grub_crypto_lookup_md_by_asn (const void *asn, grub_size_t asnlen)
{
const gcry_md_spec_t *md;
int first = 1;
while (1)
{
for (md = grub_digests; md; md = md->next)
if (md->asnlen
&& (grub_size_t) md->asnlen <= asnlen
&& grub_memcmp (asn, md->asnoid, md->asnlen) == 0)
return md;
if (grub_crypto_autoload_hook && first)
/* FIXME */
grub_crypto_autoload_hook ("sha256");
else
return NULL;
first = 0;
}
}
const gcry_cipher_spec_t *
grub_crypto_lookup_cipher_by_name (const char *name)
{

View File

@@ -29,7 +29,7 @@ void
grub_halt (void)
{
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
#if !defined(__ia64__) && !defined(__arm__)
#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__)
grub_acpi_halt ();
#endif
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,

View File

@@ -132,6 +132,7 @@ static int add_subnode (void *fdt, int parentoffset, const char *name)
+ parentoffset);
grub_uint32_t *end = (void *) struct_end (fdt);
unsigned int entry_size = node_entry_size (name);
unsigned int struct_size = grub_fdt_get_size_dt_struct(fdt);
char *node_name;
SKIP_NODE_NAME(node_name, token, end);
@@ -167,6 +168,7 @@ insert:
token[entry_size / sizeof(*token) - 2] = 0; /* padding bytes */
grub_strcpy((char *) (token + 1), name);
token[entry_size / sizeof(*token) - 1] = grub_cpu_to_be32(FDT_END_NODE);
grub_fdt_set_size_dt_struct (fdt, struct_size + entry_size);
return ((grub_addr_t) token - (grub_addr_t) fdt
- grub_fdt_get_off_dt_struct(fdt));
}

View File

@@ -247,7 +247,7 @@ extern UDItype __udiv_qrnnd ();
"=r" ((xl)) \
: "r" ((USItype)(a)), \
"r" ((USItype)(b)) \
: "r0", "r1", "r2" __CLOBBER_CC)
: "r0", "r1", "r2" __AND_CLOBBER_CC)
#else /* __ARM_ARCH >= 4 */
#define umul_ppmm(xh, xl, a, b) \
__asm__ ("@ Inlined umul_ppmm\n" \
@@ -749,7 +749,7 @@ extern USItype __udiv_qrnnd ();
************** MIPS *****************
***************************************/
#if defined (__mips__) && W_TYPE_SIZE == 32
#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
#if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
#define umul_ppmm(w1, w0, u, v) \
do { \
UDItype _r; \

Some files were not shown because too many files have changed in this diff Show More