mirror of
http://cgit.git.savannah.gnu.org/git/grub.git
synced 2026-04-28 14:33:34 +00:00
Compare commits
133 Commits
phcoder/fi
...
phcoder/ar
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67a51e8e15 | ||
|
|
5ff249072d | ||
|
|
0277eab701 | ||
|
|
4861b6c851 | ||
|
|
3100cdc7f9 | ||
|
|
ad73cc3312 | ||
|
|
4182262560 | ||
|
|
896f483d49 | ||
|
|
8c534b85f1 | ||
|
|
a846dd4b3a | ||
|
|
aa437b5890 | ||
|
|
b0f311f412 | ||
|
|
59b38922a1 | ||
|
|
0480665b9d | ||
|
|
bbeee1c4a3 | ||
|
|
e5ed2f6947 | ||
|
|
4a73746a04 | ||
|
|
382b500ebe | ||
|
|
3a82f8bb48 | ||
|
|
e3046431da | ||
|
|
bdb6090d83 | ||
|
|
b73b70ebca | ||
|
|
8a3f0a24b5 | ||
|
|
6f07c4e407 | ||
|
|
60d5e9cbd9 | ||
|
|
cd15c394cc | ||
|
|
bb6e299ccb | ||
|
|
85eb579ad9 | ||
|
|
47f88cc94e | ||
|
|
40b5739ff9 | ||
|
|
234d93464a | ||
|
|
0c0eab527f | ||
|
|
44d4884779 | ||
|
|
10955cda06 | ||
|
|
f315b508ae | ||
|
|
9e4e6ddfbf | ||
|
|
5037aa9a7b | ||
|
|
8a952d20d1 | ||
|
|
b29b77fee2 | ||
|
|
be0d45555e | ||
|
|
d74b9a1d1a | ||
|
|
35de6d4bac | ||
|
|
ce55ed0389 | ||
|
|
f70ab525f9 | ||
|
|
9b70860ecc | ||
|
|
095588ef34 | ||
|
|
2dbda2215c | ||
|
|
53cc63bf85 | ||
|
|
471b2683e7 | ||
|
|
8ddf84bfb8 | ||
|
|
fd0df6d098 | ||
|
|
69ca97c820 | ||
|
|
eec893ae49 | ||
|
|
621e167fd6 | ||
|
|
d54f647a4a | ||
|
|
c8a0f1b229 | ||
|
|
726409a513 | ||
|
|
422e6e886c | ||
|
|
af1faca3f8 | ||
|
|
469021b4b3 | ||
|
|
83c256ba42 | ||
|
|
b67422d33d | ||
|
|
827d87e9d6 | ||
|
|
8f236c1419 | ||
|
|
2d76b4d81e | ||
|
|
4f9541226c | ||
|
|
b1f742c103 | ||
|
|
16ef26fd3a | ||
|
|
cf8c80ff77 | ||
|
|
5c7206e45e | ||
|
|
fc3f2b72cd | ||
|
|
34b2003def | ||
|
|
7e90f5ad25 | ||
|
|
ab4f15013a | ||
|
|
1e4b358720 | ||
|
|
9208367d3f | ||
|
|
67b9b7afd7 | ||
|
|
c2b70d0981 | ||
|
|
bee1b5ce3f | ||
|
|
07e3b04742 | ||
|
|
ebd289335a | ||
|
|
d2f7902af0 | ||
|
|
1005bed722 | ||
|
|
d6c92cdc34 | ||
|
|
61e1b9a49d | ||
|
|
c98dd165b0 | ||
|
|
ff1c277ef8 | ||
|
|
c8f7614b98 | ||
|
|
246a434f61 | ||
|
|
5c066a81c2 | ||
|
|
78f961efe9 | ||
|
|
09bc0a577d | ||
|
|
b700a427d2 | ||
|
|
4480b95dcd | ||
|
|
e77c81f6f8 | ||
|
|
971dbee521 | ||
|
|
6f2e82be3a | ||
|
|
9eec9699b9 | ||
|
|
5ae5c54c7e | ||
|
|
7b04fe6c9e | ||
|
|
e67566ce0a | ||
|
|
f93ddcfd1c | ||
|
|
1bba40f578 | ||
|
|
f65e14dc3a | ||
|
|
14a94bba6f | ||
|
|
8109c5d4e2 | ||
|
|
a92b5cb8d8 | ||
|
|
4a23e2fe29 | ||
|
|
a3ba74104e | ||
|
|
e1c22419ac | ||
|
|
189090cee9 | ||
|
|
1a5b7b404f | ||
|
|
9cf12b20af | ||
|
|
63a45330cb | ||
|
|
4a0aaad022 | ||
|
|
095bb1bfa5 | ||
|
|
3937bd962b | ||
|
|
ddb3efc906 | ||
|
|
4e42521d8c | ||
|
|
054efe541f | ||
|
|
a0e1befb57 | ||
|
|
c36c73f681 | ||
|
|
6f4a19f59f | ||
|
|
0d8f04cd83 | ||
|
|
4906052019 | ||
|
|
c6a823e267 | ||
|
|
b7f9aedfac | ||
|
|
7dd0a30361 | ||
|
|
ca120e31f2 | ||
|
|
8a07b55a04 | ||
|
|
d3def58c52 | ||
|
|
96fa2d9d02 | ||
|
|
15a463d742 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -159,7 +159,6 @@ GPATH
|
||||
GRTAGS
|
||||
GSYMS
|
||||
GTAGS
|
||||
Makefile.tpl
|
||||
compile
|
||||
depcomp
|
||||
mdate-sh
|
||||
|
||||
611
ChangeLog
611
ChangeLog
@@ -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
17
INSTALL
@@ -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:
|
||||
|
||||
|
||||
11
Makefile.am
11
Makefile.am
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
20
acinclude.m4
20
acinclude.m4
@@ -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]
|
||||
])
|
||||
|
||||
11
autogen.sh
11
autogen.sh
@@ -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
|
||||
|
||||
@@ -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 $@
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
208
configure.ac
208
configure.ac
@@ -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])
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
107
docs/grub.texi
107
docs/grub.texi
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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."),
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
63
grub-core/kern/arm64/cache.c
Normal file
63
grub-core/kern/arm64/cache.c
Normal 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);
|
||||
}
|
||||
55
grub-core/kern/arm64/cache_flush.S
Normal file
55
grub-core/kern/arm64/cache_flush.S
Normal 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
165
grub-core/kern/arm64/dl.c
Normal 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;
|
||||
}
|
||||
55
grub-core/kern/arm64/dl_helper.c
Normal file
55
grub-core/kern/arm64/dl_helper.c
Normal 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;
|
||||
}
|
||||
39
grub-core/kern/arm64/efi/startup.S
Normal file
39
grub-core/kern/arm64/efi/startup.S
Normal 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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -166,6 +166,8 @@ static struct argp argp = {
|
||||
|
||||
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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, ...)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
53
grub-core/lib/arm64/setjmp.S
Normal file
53
grub-core/lib/arm64/setjmp.S
Normal 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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user