mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-08-28 00:11:15 +00:00
experimental support for loongson mips64el uefi
This commit is contained in:
1000
GRUB2/MOD_SRC/grub-2.04/util/grub-install-common.c
Normal file
1000
GRUB2/MOD_SRC/grub-2.04/util/grub-install-common.c
Normal file
File diff suppressed because it is too large
Load Diff
1981
GRUB2/MOD_SRC/grub-2.04/util/grub-install.c
Normal file
1981
GRUB2/MOD_SRC/grub-2.04/util/grub-install.c
Normal file
File diff suppressed because it is too large
Load Diff
373
GRUB2/MOD_SRC/grub-2.04/util/grub-mkconfig_lib.in
Normal file
373
GRUB2/MOD_SRC/grub-2.04/util/grub-mkconfig_lib.in
Normal file
@@ -0,0 +1,373 @@
|
||||
# Helper library for grub-mkconfig
|
||||
# Copyright (C) 2007,2008,2009,2010 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/>.
|
||||
|
||||
prefix="@prefix@"
|
||||
exec_prefix="@exec_prefix@"
|
||||
datarootdir="@datarootdir@"
|
||||
datadir="@datadir@"
|
||||
bindir="@bindir@"
|
||||
sbindir="@sbindir@"
|
||||
if [ "x$pkgdatadir" = x ]; then
|
||||
pkgdatadir="${datadir}/@PACKAGE@"
|
||||
fi
|
||||
|
||||
if test "x$grub_probe" = x; then
|
||||
grub_probe="${sbindir}/@grub_probe@"
|
||||
fi
|
||||
if test "x$grub_file" = x; then
|
||||
grub_file="${bindir}/@grub_file@"
|
||||
fi
|
||||
if test "x$grub_mkrelpath" = x; then
|
||||
grub_mkrelpath="${bindir}/@grub_mkrelpath@"
|
||||
fi
|
||||
|
||||
if which gettext >/dev/null 2>/dev/null; then
|
||||
:
|
||||
else
|
||||
gettext () {
|
||||
printf "%s" "$@"
|
||||
}
|
||||
fi
|
||||
|
||||
grub_warn ()
|
||||
{
|
||||
echo "$(gettext "Warning:")" "$@" >&2
|
||||
}
|
||||
|
||||
make_system_path_relative_to_its_root ()
|
||||
{
|
||||
"${grub_mkrelpath}" "$1"
|
||||
}
|
||||
|
||||
is_path_readable_by_grub ()
|
||||
{
|
||||
path="$1"
|
||||
|
||||
# abort if path doesn't exist
|
||||
if test -e "$path" ; then : ;else
|
||||
return 1
|
||||
fi
|
||||
|
||||
# abort if file is in a filesystem we can't read
|
||||
if "${grub_probe}" -t fs "$path" > /dev/null 2>&1 ; then : ; else
|
||||
return 1
|
||||
fi
|
||||
|
||||
# ... or if we can't figure out the abstraction module, for example if
|
||||
# memberlist fails on an LVM volume group.
|
||||
if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2> /dev/null ; then
|
||||
:
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
for abstraction in $abstractions; do
|
||||
if [ "x$abstraction" = xcryptodisk ]; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
convert_system_path_to_grub_path ()
|
||||
{
|
||||
path="$1"
|
||||
|
||||
grub_warn "convert_system_path_to_grub_path() is deprecated. Use prepare_grub_to_access_device() instead."
|
||||
|
||||
# abort if GRUB can't access the path
|
||||
if is_path_readable_by_grub "${path}" ; then : ; else
|
||||
return 1
|
||||
fi
|
||||
|
||||
if drive="`"${grub_probe}" -t drive "$path"`" ; then : ; else
|
||||
return 1
|
||||
fi
|
||||
|
||||
if relative_path="`make_system_path_relative_to_its_root "$path"`" ; then : ; else
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "${drive}${relative_path}"
|
||||
}
|
||||
|
||||
save_default_entry ()
|
||||
{
|
||||
if [ "x${GRUB_SAVEDEFAULT}" = "xtrue" ] ; then
|
||||
cat << EOF
|
||||
savedefault
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_grub_to_access_device ()
|
||||
{
|
||||
old_ifs="$IFS"
|
||||
IFS='
|
||||
'
|
||||
:<<\EOF
|
||||
partmap="`"${grub_probe}" --device $@ --target=partmap`"
|
||||
for module in ${partmap} ; do
|
||||
case "${module}" in
|
||||
netbsd | openbsd)
|
||||
echo "insmod part_bsd";;
|
||||
*)
|
||||
echo "insmod part_${module}";;
|
||||
esac
|
||||
done
|
||||
EOF
|
||||
|
||||
# Abstraction modules aren't auto-loaded.
|
||||
abstraction="`"${grub_probe}" --device $@ --target=abstraction`"
|
||||
for module in ${abstraction} ; do
|
||||
echo "insmod ${module}"
|
||||
done
|
||||
|
||||
# fs="`"${grub_probe}" --device $@ --target=fs`"
|
||||
# for module in ${fs} ; do
|
||||
# echo "insmod ${module}"
|
||||
# done
|
||||
|
||||
if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
|
||||
for uuid in `"${grub_probe}" --device $@ --target=cryptodisk_uuid`; do
|
||||
echo "cryptomount -u $uuid"
|
||||
done
|
||||
fi
|
||||
|
||||
# If there's a filesystem UUID that GRUB is capable of identifying, use it;
|
||||
# otherwise set root as per value in device.map.
|
||||
fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`"
|
||||
if [ "x$fs_hint" != x ]; then
|
||||
echo "set root='$fs_hint'"
|
||||
fi
|
||||
if fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then
|
||||
hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints=
|
||||
echo "if [ x\$feature_platform_search_hint = xy ]; then"
|
||||
echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
|
||||
echo "else"
|
||||
echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}"
|
||||
echo "fi"
|
||||
fi
|
||||
IFS="$old_ifs"
|
||||
}
|
||||
|
||||
grub_get_device_id ()
|
||||
{
|
||||
old_ifs="$IFS"
|
||||
IFS='
|
||||
'
|
||||
device="$1"
|
||||
if fs_uuid="`"${grub_probe}" --device ${device} --target=fs_uuid 2> /dev/null`" ; then
|
||||
echo "$fs_uuid";
|
||||
else
|
||||
echo $device |sed 's, ,_,g'
|
||||
fi
|
||||
IFS="$old_ifs"
|
||||
}
|
||||
|
||||
grub_file_is_not_garbage ()
|
||||
{
|
||||
if test -f "$1" ; then
|
||||
case "$1" in
|
||||
*.dpkg-*) return 1 ;; # debian dpkg
|
||||
*.rpmsave|*.rpmnew) return 1 ;;
|
||||
README*|*/README*) return 1 ;; # documentation
|
||||
*.sig) return 1 ;; # signatures
|
||||
esac
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
version_sort ()
|
||||
{
|
||||
case $version_sort_sort_has_v in
|
||||
yes)
|
||||
LC_ALL=C sort -V;;
|
||||
no)
|
||||
LC_ALL=C sort -n;;
|
||||
*)
|
||||
if sort -V </dev/null > /dev/null 2>&1; then
|
||||
version_sort_sort_has_v=yes
|
||||
LC_ALL=C sort -V
|
||||
else
|
||||
version_sort_sort_has_v=no
|
||||
LC_ALL=C sort -n
|
||||
fi;;
|
||||
esac
|
||||
}
|
||||
|
||||
version_test_numeric ()
|
||||
{
|
||||
version_test_numeric_a="$1"
|
||||
version_test_numeric_cmp="$2"
|
||||
version_test_numeric_b="$3"
|
||||
if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then
|
||||
case "$version_test_numeric_cmp" in
|
||||
ge|eq|le) return 0 ;;
|
||||
gt|lt) return 1 ;;
|
||||
esac
|
||||
fi
|
||||
if [ "$version_test_numeric_cmp" = "lt" ] ; then
|
||||
version_test_numeric_c="$version_test_numeric_a"
|
||||
version_test_numeric_a="$version_test_numeric_b"
|
||||
version_test_numeric_b="$version_test_numeric_c"
|
||||
fi
|
||||
if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
version_test_gt ()
|
||||
{
|
||||
version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`"
|
||||
version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`"
|
||||
version_test_gt_cmp=gt
|
||||
if [ "x$version_test_gt_b" = "x" ] ; then
|
||||
return 0
|
||||
fi
|
||||
case "$version_test_gt_a:$version_test_gt_b" in
|
||||
*.old:*.old) ;;
|
||||
*.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;;
|
||||
*:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;;
|
||||
esac
|
||||
version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b"
|
||||
return "$?"
|
||||
}
|
||||
|
||||
version_find_latest ()
|
||||
{
|
||||
version_find_latest_a=""
|
||||
for i in "$@" ; do
|
||||
if version_test_gt "$i" "$version_find_latest_a" ; then
|
||||
version_find_latest_a="$i"
|
||||
fi
|
||||
done
|
||||
echo "$version_find_latest_a"
|
||||
}
|
||||
|
||||
# One layer of quotation is eaten by "" and the second by sed; so this turns
|
||||
# ' into \'.
|
||||
grub_quote () {
|
||||
sed "s/'/'\\\\''/g"
|
||||
}
|
||||
|
||||
gettext_quoted () {
|
||||
gettext "$@" | grub_quote
|
||||
}
|
||||
|
||||
# Run the first argument through gettext, and then pass that and all
|
||||
# remaining arguments to printf. This is a useful abbreviation and tends to
|
||||
# be easier to type.
|
||||
gettext_printf () {
|
||||
gettext_printf_format="$1"
|
||||
shift
|
||||
printf "$(gettext "$gettext_printf_format")" "$@"
|
||||
}
|
||||
|
||||
uses_abstraction () {
|
||||
device="$1"
|
||||
old_ifs="$IFS"
|
||||
IFS='
|
||||
'
|
||||
|
||||
abstraction="`"${grub_probe}" --device ${device} --target=abstraction`"
|
||||
for module in ${abstraction}; do
|
||||
if test "x${module}" = "x$2"; then
|
||||
IFS="$old_ifs"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
IFS="$old_ifs"
|
||||
return 1
|
||||
}
|
||||
|
||||
print_option_help () {
|
||||
if test x$print_option_help_wc = x; then
|
||||
if wc -L </dev/null > /dev/null 2>&1; then
|
||||
print_option_help_wc=-L
|
||||
elif wc -m </dev/null > /dev/null 2>&1; then
|
||||
print_option_help_wc=-m
|
||||
else
|
||||
print_option_help_wc=-b
|
||||
fi
|
||||
fi
|
||||
if test x$grub_have_fmt = x; then
|
||||
if fmt -w 40 </dev/null > /dev/null 2>&1; then
|
||||
grub_have_fmt=y;
|
||||
else
|
||||
grub_have_fmt=n;
|
||||
fi
|
||||
fi
|
||||
print_option_help_lead=" $1"
|
||||
print_option_help_lspace="$(echo "$print_option_help_lead" | wc $print_option_help_wc)"
|
||||
print_option_help_fill="$((26 - print_option_help_lspace))"
|
||||
printf "%s" "$print_option_help_lead"
|
||||
if test $print_option_help_fill -le 0; then
|
||||
print_option_help_nl=y
|
||||
echo
|
||||
else
|
||||
print_option_help_i=0;
|
||||
while test $print_option_help_i -lt $print_option_help_fill; do
|
||||
printf " "
|
||||
print_option_help_i=$((print_option_help_i+1))
|
||||
done
|
||||
print_option_help_nl=n
|
||||
fi
|
||||
if test x$grub_have_fmt = xy; then
|
||||
print_option_help_split="$(echo "$2" | fmt -w 50)"
|
||||
else
|
||||
print_option_help_split="$2"
|
||||
fi
|
||||
if test x$print_option_help_nl = xy; then
|
||||
echo "$print_option_help_split" | awk \
|
||||
'{ print " " $0; }'
|
||||
else
|
||||
echo "$print_option_help_split" | awk 'BEGIN { n = 0 }
|
||||
{ if (n == 1) print " " $0; else print $0; n = 1 ; }'
|
||||
fi
|
||||
}
|
||||
|
||||
grub_fmt () {
|
||||
if test x$grub_have_fmt = x; then
|
||||
if fmt -w 40 < /dev/null > /dev/null; then
|
||||
grub_have_fmt=y;
|
||||
else
|
||||
grub_have_fmt=n;
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$grub_have_fmt = xy; then
|
||||
fmt
|
||||
else
|
||||
cat
|
||||
fi
|
||||
}
|
||||
|
||||
grub_tab=" "
|
||||
|
||||
grub_add_tab () {
|
||||
sed -e "s/^/$grub_tab/"
|
||||
}
|
||||
|
2689
GRUB2/MOD_SRC/grub-2.04/util/grub-mkimagexx.c
Normal file
2689
GRUB2/MOD_SRC/grub-2.04/util/grub-mkimagexx.c
Normal file
File diff suppressed because it is too large
Load Diff
225
GRUB2/MOD_SRC/grub-2.04/util/grub-mknetdir.c
Normal file
225
GRUB2/MOD_SRC/grub-2.04/util/grub-mknetdir.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,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 <config.h>
|
||||
|
||||
#include <grub/util/install.h>
|
||||
#include <grub/emu/config.h>
|
||||
#include <grub/util/misc.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-declarations"
|
||||
#include <argp.h>
|
||||
#pragma GCC diagnostic error "-Wmissing-prototypes"
|
||||
#pragma GCC diagnostic error "-Wmissing-declarations"
|
||||
|
||||
static char *rootdir = NULL, *subdir = NULL;
|
||||
static char *debug_image = NULL;
|
||||
|
||||
enum
|
||||
{
|
||||
OPTION_NET_DIRECTORY = 0x301,
|
||||
OPTION_SUBDIR,
|
||||
OPTION_DEBUG,
|
||||
OPTION_DEBUG_IMAGE
|
||||
};
|
||||
|
||||
static struct argp_option options[] = {
|
||||
GRUB_INSTALL_OPTIONS,
|
||||
{"net-directory", OPTION_NET_DIRECTORY, N_("DIR"),
|
||||
0, N_("root directory of TFTP server"), 2},
|
||||
{"subdir", OPTION_SUBDIR, N_("DIR"),
|
||||
0, N_("relative subdirectory on network server"), 2},
|
||||
{"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
|
||||
{"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static error_t
|
||||
argp_parser (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
if (grub_install_parse (key, arg))
|
||||
return 0;
|
||||
switch (key)
|
||||
{
|
||||
case OPTION_NET_DIRECTORY:
|
||||
free (rootdir);
|
||||
rootdir = xstrdup (arg);
|
||||
return 0;
|
||||
case OPTION_SUBDIR:
|
||||
free (subdir);
|
||||
subdir = xstrdup (arg);
|
||||
return 0;
|
||||
/* This is an undocumented feature... */
|
||||
case OPTION_DEBUG:
|
||||
verbosity++;
|
||||
return 0;
|
||||
case OPTION_DEBUG_IMAGE:
|
||||
free (debug_image);
|
||||
debug_image = xstrdup (arg);
|
||||
return 0;
|
||||
|
||||
case ARGP_KEY_ARG:
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct argp argp = {
|
||||
options, argp_parser, NULL,
|
||||
"\v"N_("Prepares GRUB network boot images at net_directory/subdir "
|
||||
"assuming net_directory being TFTP root."),
|
||||
NULL, grub_install_help_filter, NULL
|
||||
};
|
||||
|
||||
static char *base;
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *mkimage_target;
|
||||
const char *netmodule;
|
||||
const char *ext;
|
||||
} targets[GRUB_INSTALL_PLATFORM_MAX] =
|
||||
{
|
||||
[GRUB_INSTALL_PLATFORM_I386_PC] = { "i386-pc-pxe", "pxe", ".0" },
|
||||
[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64-ieee1275-aout", "ofnet", ".img" },
|
||||
[GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386-ieee1275", "ofnet", ".elf" },
|
||||
[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc-ieee1275", "ofnet", ".elf" },
|
||||
[GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] = { "mips64el-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32-efi", "efinet", ".efi" },
|
||||
[GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64-efi", "efinet", ".efi" },
|
||||
};
|
||||
|
||||
static void
|
||||
process_input_dir (const char *input_dir, enum grub_install_plat platform)
|
||||
{
|
||||
char *platsub = grub_install_get_platform_name (platform);
|
||||
char *grubdir = grub_util_path_concat (3, rootdir, subdir, platsub);
|
||||
char *load_cfg = grub_util_path_concat (2, grubdir, "load.cfg");
|
||||
char *prefix;
|
||||
char *output;
|
||||
char *grub_cfg;
|
||||
FILE *cfg;
|
||||
|
||||
grub_install_copy_files (input_dir, base, platform);
|
||||
grub_util_unlink (load_cfg);
|
||||
|
||||
if (debug_image)
|
||||
{
|
||||
FILE *f = grub_util_fopen (load_cfg, "wb");
|
||||
if (!f)
|
||||
grub_util_error (_("cannot open `%s': %s"), load_cfg,
|
||||
strerror (errno));
|
||||
fprintf (f, "set debug='%s'\n", debug_image);
|
||||
fclose (f);
|
||||
}
|
||||
else
|
||||
{
|
||||
free (load_cfg);
|
||||
load_cfg = 0;
|
||||
}
|
||||
|
||||
prefix = xasprintf ("/%s", subdir);
|
||||
if (!targets[platform].mkimage_target)
|
||||
grub_util_error (_("unsupported platform %s"), platsub);
|
||||
|
||||
grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg");
|
||||
cfg = grub_util_fopen (grub_cfg, "wb");
|
||||
if (!cfg)
|
||||
grub_util_error (_("cannot open `%s': %s"), grub_cfg,
|
||||
strerror (errno));
|
||||
fprintf (cfg, "source %s/grub.cfg", subdir);
|
||||
fclose (cfg);
|
||||
|
||||
grub_install_push_module (targets[platform].netmodule);
|
||||
|
||||
output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext);
|
||||
grub_install_make_image_wrap (input_dir, prefix, output,
|
||||
0, load_cfg,
|
||||
targets[platform].mkimage_target, 0);
|
||||
grub_install_pop_module ();
|
||||
|
||||
/* TRANSLATORS: First %s is replaced by platform name. Second one by filename. */
|
||||
printf (_("Netboot directory for %s created. Configure your DHCP server to point to %s\n"),
|
||||
platsub, output);
|
||||
|
||||
free (platsub);
|
||||
free (output);
|
||||
free (prefix);
|
||||
free (grub_cfg);
|
||||
free (grubdir);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
const char *pkglibdir;
|
||||
|
||||
grub_util_host_init (&argc, &argv);
|
||||
grub_util_disable_fd_syncs ();
|
||||
rootdir = xstrdup ("/srv/tftp");
|
||||
pkglibdir = grub_util_get_pkglibdir ();
|
||||
|
||||
subdir = grub_util_path_concat (2, GRUB_BOOT_DIR_NAME, GRUB_DIR_NAME);
|
||||
|
||||
argp_parse (&argp, argc, argv, 0, 0, 0);
|
||||
|
||||
base = grub_util_path_concat (2, rootdir, subdir);
|
||||
/* Create the GRUB directory if it is not present. */
|
||||
|
||||
grub_install_mkdir_p (base);
|
||||
|
||||
grub_install_push_module ("tftp");
|
||||
|
||||
if (!grub_install_source_directory)
|
||||
{
|
||||
enum grub_install_plat plat;
|
||||
|
||||
for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
|
||||
if (targets[plat].mkimage_target)
|
||||
{
|
||||
char *platdir = grub_util_path_concat (2, pkglibdir,
|
||||
grub_install_get_platform_name (plat));
|
||||
|
||||
grub_util_info ("Looking for `%s'", platdir);
|
||||
|
||||
if (!grub_util_is_directory (platdir))
|
||||
{
|
||||
free (platdir);
|
||||
continue;
|
||||
}
|
||||
process_input_dir (platdir, plat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
enum grub_install_plat plat;
|
||||
plat = grub_install_get_target (grub_install_source_directory);
|
||||
process_input_dir (grub_install_source_directory, plat);
|
||||
}
|
||||
return 0;
|
||||
}
|
1003
GRUB2/MOD_SRC/grub-2.04/util/grub-mkrescue.c
Normal file
1003
GRUB2/MOD_SRC/grub-2.04/util/grub-mkrescue.c
Normal file
File diff suppressed because it is too large
Load Diff
247
GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifier.c
Normal file
247
GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifier.c
Normal file
@@ -0,0 +1,247 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <grub/elf.h>
|
||||
#include <grub/module_verifier.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/util/misc.h>
|
||||
|
||||
struct grub_module_verifier_arch archs[] = {
|
||||
{ "i386", 4, 0, EM_386, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){
|
||||
R_386_32,
|
||||
R_386_PC32,
|
||||
-1
|
||||
} },
|
||||
{ "x86_64", 8, 0, EM_X86_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_X86_64_64,
|
||||
R_X86_64_PC64,
|
||||
/* R_X86_64_32, R_X86_64_32S are supported but shouldn't be used because of their limited range. */
|
||||
-1
|
||||
}, (int[]){
|
||||
R_X86_64_PC32,
|
||||
R_X86_64_PLT32,
|
||||
-1
|
||||
}
|
||||
},
|
||||
{ "powerpc", 4, 1, EM_PPC, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
GRUB_ELF_R_PPC_ADDR16_LO,
|
||||
GRUB_ELF_R_PPC_REL24, /* It has limited range but GRUB adds trampolines when necessarry. */
|
||||
GRUB_ELF_R_PPC_ADDR16_HA,
|
||||
GRUB_ELF_R_PPC_ADDR32,
|
||||
GRUB_ELF_R_PPC_REL32,
|
||||
GRUB_ELF_R_PPC_PLTREL24,
|
||||
-1
|
||||
} },
|
||||
{ "sparc64", 8, 1, EM_SPARCV9, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_SPARC_WDISP30, /* It has limited range but GRUB adds trampolines when necessarry. */
|
||||
R_SPARC_HH22,
|
||||
R_SPARC_HM10,
|
||||
R_SPARC_LM22,
|
||||
R_SPARC_LO10,
|
||||
R_SPARC_64,
|
||||
R_SPARC_OLO10,
|
||||
/* Following 2 relocations have limited range but unfortunately
|
||||
clang generates them, as it doesn't implement mcmodel=large properly.
|
||||
At least our heap and core are under 4G, so it's not a problem
|
||||
usually. */
|
||||
R_SPARC_HI22,
|
||||
R_SPARC_32,
|
||||
-1
|
||||
} },
|
||||
{ "ia64", 8, 0, EM_IA_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_IA64_PCREL21B, /* We should verify that it's pointing either
|
||||
to a function or to a section in the same module.
|
||||
Checking that external symbol is a function is
|
||||
non-trivial and I have never seen this relocation used
|
||||
for anything else, so assume that it always points to a
|
||||
function.
|
||||
*/
|
||||
R_IA64_SEGREL64LSB,
|
||||
R_IA64_FPTR64LSB,
|
||||
R_IA64_DIR64LSB,
|
||||
R_IA64_PCREL64LSB,
|
||||
R_IA64_LTOFF22X,
|
||||
R_IA64_LTOFF22,
|
||||
R_IA64_GPREL64I,
|
||||
R_IA64_LTOFF_FPTR22,
|
||||
R_IA64_LDXMOV,
|
||||
-1
|
||||
}, (int[]){
|
||||
R_IA64_GPREL22,
|
||||
-1
|
||||
} },
|
||||
{ "mipsel", 4, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_MIPS_HI16,
|
||||
R_MIPS_LO16,
|
||||
R_MIPS_32,
|
||||
R_MIPS_GPREL32,
|
||||
R_MIPS_26,
|
||||
R_MIPS_GOT16,
|
||||
R_MIPS_CALL16,
|
||||
R_MIPS_JALR,
|
||||
-1
|
||||
} },
|
||||
{ "mips", 4, 1, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_MIPS_HI16,
|
||||
R_MIPS_LO16,
|
||||
R_MIPS_32,
|
||||
R_MIPS_GPREL32,
|
||||
R_MIPS_26,
|
||||
R_MIPS_GOT16,
|
||||
R_MIPS_CALL16,
|
||||
R_MIPS_JALR,
|
||||
-1
|
||||
} },
|
||||
{ "arm", 4, 0, EM_ARM, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){
|
||||
/* Some relocations are range-limited but trampolines are added when necessarry. */
|
||||
R_ARM_ABS32,
|
||||
R_ARM_CALL,
|
||||
R_ARM_JUMP24,
|
||||
R_ARM_THM_CALL,
|
||||
R_ARM_THM_JUMP24,
|
||||
R_ARM_V4BX,
|
||||
R_ARM_THM_MOVW_ABS_NC,
|
||||
R_ARM_THM_MOVT_ABS,
|
||||
R_ARM_THM_JUMP19,
|
||||
-1
|
||||
} },
|
||||
{ "arm64", 8, 0, EM_AARCH64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_AARCH64_ABS64,
|
||||
R_AARCH64_CALL26,
|
||||
R_AARCH64_JUMP26,
|
||||
R_AARCH64_ADR_GOT_PAGE,
|
||||
R_AARCH64_LD64_GOT_LO12_NC,
|
||||
-1
|
||||
}, (int[]){
|
||||
R_AARCH64_ADR_PREL_PG_HI21,
|
||||
R_AARCH64_ADD_ABS_LO12_NC,
|
||||
R_AARCH64_LDST64_ABS_LO12_NC,
|
||||
R_AARCH64_PREL32,
|
||||
-1
|
||||
} },
|
||||
{ "mips64el", 8, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_MIPS_64,
|
||||
R_MIPS_32,
|
||||
R_MIPS_26,
|
||||
R_MIPS_LO16,
|
||||
R_MIPS_HI16,
|
||||
R_MIPS_HIGHER,
|
||||
R_MIPS_HIGHEST,
|
||||
-1
|
||||
}, (int[]){
|
||||
-1
|
||||
}
|
||||
},
|
||||
{ "riscv32", 4, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_RISCV_32,
|
||||
R_RISCV_64,
|
||||
R_RISCV_ADD8,
|
||||
R_RISCV_ADD16,
|
||||
R_RISCV_ADD32,
|
||||
R_RISCV_ADD64,
|
||||
R_RISCV_SUB8,
|
||||
R_RISCV_SUB16,
|
||||
R_RISCV_SUB32,
|
||||
R_RISCV_SUB64,
|
||||
R_RISCV_ALIGN,
|
||||
R_RISCV_BRANCH,
|
||||
R_RISCV_CALL,
|
||||
R_RISCV_CALL_PLT,
|
||||
R_RISCV_GOT_HI20,
|
||||
R_RISCV_HI20,
|
||||
R_RISCV_JAL,
|
||||
R_RISCV_LO12_I,
|
||||
R_RISCV_LO12_S,
|
||||
R_RISCV_PCREL_HI20,
|
||||
R_RISCV_PCREL_LO12_I,
|
||||
R_RISCV_PCREL_LO12_S,
|
||||
R_RISCV_RELAX,
|
||||
R_RISCV_RVC_BRANCH,
|
||||
R_RISCV_RVC_JUMP,
|
||||
-1
|
||||
} },
|
||||
{ "riscv64", 8, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
|
||||
R_RISCV_32,
|
||||
R_RISCV_64,
|
||||
R_RISCV_ADD8,
|
||||
R_RISCV_ADD16,
|
||||
R_RISCV_ADD32,
|
||||
R_RISCV_ADD64,
|
||||
R_RISCV_SUB8,
|
||||
R_RISCV_SUB16,
|
||||
R_RISCV_SUB32,
|
||||
R_RISCV_SUB64,
|
||||
R_RISCV_ALIGN,
|
||||
R_RISCV_BRANCH,
|
||||
R_RISCV_CALL,
|
||||
R_RISCV_CALL_PLT,
|
||||
R_RISCV_GOT_HI20,
|
||||
R_RISCV_HI20,
|
||||
R_RISCV_JAL,
|
||||
R_RISCV_LO12_I,
|
||||
R_RISCV_LO12_S,
|
||||
R_RISCV_PCREL_HI20,
|
||||
R_RISCV_PCREL_LO12_I,
|
||||
R_RISCV_PCREL_LO12_S,
|
||||
R_RISCV_RELAX,
|
||||
R_RISCV_RVC_BRANCH,
|
||||
R_RISCV_RVC_JUMP,
|
||||
-1
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_whitelist {
|
||||
const char *arch;
|
||||
const char *platform;
|
||||
const char **whitelist_empty;
|
||||
};
|
||||
|
||||
static struct platform_whitelist whitelists[] = {
|
||||
{"i386", "xen", (const char *[]) {"all_video", 0}},
|
||||
{"i386", "xen_pvh", (const char *[]) {"all_video", 0}},
|
||||
{"x86_64", "xen", (const char *[]) {"all_video", 0}},
|
||||
{"sparc64", "ieee1275", (const char *[]) {"all_video", 0}},
|
||||
|
||||
/* video is compiled-in on MIPS. */
|
||||
{"mipsel", "loongson", (const char *[]) {"all_video", 0}},
|
||||
{"mipsel", "qemu_mips", (const char *[]) {"all_video", 0}},
|
||||
{"mipsel", "arc", (const char *[]) {"all_video", 0}},
|
||||
{"mips", "qemu_mips", (const char *[]) {"all_video", 0}},
|
||||
{"mips", "arc", (const char *[]) {"all_video", 0}},
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
size_t module_size;
|
||||
unsigned arch, whitelist;
|
||||
const char **whitelist_empty = 0;
|
||||
char *module_img;
|
||||
if (argc != 4) {
|
||||
fprintf (stderr, "usage: %s FILE ARCH PLATFORM\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (arch = 0; arch < ARRAY_SIZE(archs); arch++)
|
||||
if (strcmp(archs[arch].name, argv[2]) == 0)
|
||||
break;
|
||||
if (arch == ARRAY_SIZE(archs))
|
||||
grub_util_error("%s: unknown arch: %s", argv[1], argv[2]);
|
||||
|
||||
for (whitelist = 0; whitelist < ARRAY_SIZE(whitelists); whitelist++)
|
||||
if (strcmp(whitelists[whitelist].arch, argv[2]) == 0
|
||||
&& strcmp(whitelists[whitelist].platform, argv[3]) == 0)
|
||||
break;
|
||||
if (whitelist != ARRAY_SIZE(whitelists))
|
||||
whitelist_empty = whitelists[whitelist].whitelist_empty;
|
||||
|
||||
module_size = grub_util_get_image_size (argv[1]);
|
||||
module_img = grub_util_read_image (argv[1]);
|
||||
if (archs[arch].voidp_sizeof == 8)
|
||||
grub_module_verify64(argv[1], module_img, module_size, &archs[arch], whitelist_empty);
|
||||
else
|
||||
grub_module_verify32(argv[1], module_img, module_size, &archs[arch], whitelist_empty);
|
||||
return 0;
|
||||
}
|
446
GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifierXX.c
Normal file
446
GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifierXX.c
Normal file
@@ -0,0 +1,446 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <grub/elf.h>
|
||||
#include <grub/module_verifier.h>
|
||||
#include <grub/util/misc.h>
|
||||
|
||||
#if defined(MODULEVERIFIER_ELF32)
|
||||
# define SUFFIX(x) x ## 32
|
||||
# define ELFCLASSXX ELFCLASS32
|
||||
# define Elf_Ehdr Elf32_Ehdr
|
||||
# define Elf_Phdr Elf32_Phdr
|
||||
# define Elf_Nhdr Elf32_Nhdr
|
||||
# define Elf_Addr Elf32_Addr
|
||||
# define Elf_Sym Elf32_Sym
|
||||
# define Elf_Off Elf32_Off
|
||||
# define Elf_Shdr Elf32_Shdr
|
||||
# define Elf_Rela Elf32_Rela
|
||||
# define Elf_Rel Elf32_Rel
|
||||
# define Elf_Word Elf32_Word
|
||||
# define Elf_Half Elf32_Half
|
||||
# define Elf_Section Elf32_Section
|
||||
# define ELF_R_SYM(val) ELF32_R_SYM(val)
|
||||
# define ELF_R_TYPE(val) ELF32_R_TYPE(val)
|
||||
# define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
|
||||
#elif defined(MODULEVERIFIER_ELF64)
|
||||
# define SUFFIX(x) x ## 64
|
||||
# define ELFCLASSXX ELFCLASS64
|
||||
# define Elf_Ehdr Elf64_Ehdr
|
||||
# define Elf_Phdr Elf64_Phdr
|
||||
# define Elf_Nhdr Elf64_Nhdr
|
||||
# define Elf_Addr Elf64_Addr
|
||||
# define Elf_Sym Elf64_Sym
|
||||
# define Elf_Off Elf64_Off
|
||||
# define Elf_Shdr Elf64_Shdr
|
||||
# define Elf_Rela Elf64_Rela
|
||||
# define Elf_Rel Elf64_Rel
|
||||
# define Elf_Word Elf64_Word
|
||||
# define Elf_Half Elf64_Half
|
||||
# define Elf_Section Elf64_Section
|
||||
# define ELF_R_SYM(val) ELF64_R_SYM(val)
|
||||
# define ELF_R_TYPE(val) ELF64_R_TYPE(val)
|
||||
# define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
|
||||
#else
|
||||
#error "I'm confused"
|
||||
#endif
|
||||
|
||||
#define grub_target_to_host32(x) (grub_target_to_host32_real (arch, (x)))
|
||||
#define grub_host_to_target32(x) (grub_host_to_target32_real (arch, (x)))
|
||||
#define grub_target_to_host64(x) (grub_target_to_host64_real (arch, (x)))
|
||||
#define grub_host_to_target64(x) (grub_host_to_target64_real (arch, (x)))
|
||||
#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (arch, (x)))
|
||||
#define grub_target_to_host16(x) (grub_target_to_host16_real (arch, (x)))
|
||||
#define grub_host_to_target16(x) (grub_host_to_target16_real (arch, (x)))
|
||||
#define grub_target_to_host(val) grub_target_to_host_real(arch, (val))
|
||||
|
||||
static inline grub_uint32_t
|
||||
grub_target_to_host32_real (const struct grub_module_verifier_arch *arch,
|
||||
grub_uint32_t in)
|
||||
{
|
||||
if (arch->bigendian)
|
||||
return grub_be_to_cpu32 (in);
|
||||
else
|
||||
return grub_le_to_cpu32 (in);
|
||||
}
|
||||
|
||||
static inline grub_uint64_t
|
||||
grub_target_to_host64_real (const struct grub_module_verifier_arch *arch,
|
||||
grub_uint64_t in)
|
||||
{
|
||||
if (arch->bigendian)
|
||||
return grub_be_to_cpu64 (in);
|
||||
else
|
||||
return grub_le_to_cpu64 (in);
|
||||
}
|
||||
|
||||
static inline grub_uint64_t
|
||||
grub_host_to_target64_real (const struct grub_module_verifier_arch *arch,
|
||||
grub_uint64_t in)
|
||||
{
|
||||
if (arch->bigendian)
|
||||
return grub_cpu_to_be64 (in);
|
||||
else
|
||||
return grub_cpu_to_le64 (in);
|
||||
}
|
||||
|
||||
static inline grub_uint32_t
|
||||
grub_host_to_target32_real (const struct grub_module_verifier_arch *arch,
|
||||
grub_uint32_t in)
|
||||
{
|
||||
if (arch->bigendian)
|
||||
return grub_cpu_to_be32 (in);
|
||||
else
|
||||
return grub_cpu_to_le32 (in);
|
||||
}
|
||||
|
||||
static inline grub_uint16_t
|
||||
grub_target_to_host16_real (const struct grub_module_verifier_arch *arch,
|
||||
grub_uint16_t in)
|
||||
{
|
||||
if (arch->bigendian)
|
||||
return grub_be_to_cpu16 (in);
|
||||
else
|
||||
return grub_le_to_cpu16 (in);
|
||||
}
|
||||
|
||||
static inline grub_uint16_t
|
||||
grub_host_to_target16_real (const struct grub_module_verifier_arch *arch,
|
||||
grub_uint16_t in)
|
||||
{
|
||||
if (arch->bigendian)
|
||||
return grub_cpu_to_be16 (in);
|
||||
else
|
||||
return grub_cpu_to_le16 (in);
|
||||
}
|
||||
|
||||
static inline grub_uint64_t
|
||||
grub_host_to_target_addr_real (const struct grub_module_verifier_arch *arch, grub_uint64_t in)
|
||||
{
|
||||
if (arch->voidp_sizeof == 8)
|
||||
return grub_host_to_target64_real (arch, in);
|
||||
else
|
||||
return grub_host_to_target32_real (arch, in);
|
||||
}
|
||||
|
||||
static inline grub_uint64_t
|
||||
grub_target_to_host_real (const struct grub_module_verifier_arch *arch, grub_uint64_t in)
|
||||
{
|
||||
if (arch->voidp_sizeof == 8)
|
||||
return grub_target_to_host64_real (arch, in);
|
||||
else
|
||||
return grub_target_to_host32_real (arch, in);
|
||||
}
|
||||
|
||||
|
||||
static Elf_Shdr *
|
||||
find_section (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const char *name)
|
||||
{
|
||||
Elf_Shdr *s;
|
||||
const char *str;
|
||||
unsigned i;
|
||||
|
||||
s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host16 (e->e_shstrndx) * grub_target_to_host16 (e->e_shentsize));
|
||||
str = (char *) e + grub_target_to_host (s->sh_offset);
|
||||
|
||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff));
|
||||
i < grub_target_to_host16 (e->e_shnum);
|
||||
i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize)))
|
||||
if (strcmp (str + grub_target_to_host32 (s->sh_name), name) == 0)
|
||||
return s;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
check_license (const char * const filename,
|
||||
const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
|
||||
{
|
||||
Elf_Shdr *s = find_section (arch, e, ".module_license");
|
||||
if (s && (strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3") == 0
|
||||
|| strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3+") == 0
|
||||
|| strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv2+") == 0))
|
||||
return;
|
||||
grub_util_error ("%s: incompatible license", filename);
|
||||
}
|
||||
|
||||
static Elf_Sym *
|
||||
get_symtab (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word *size, Elf_Word *entsize)
|
||||
{
|
||||
unsigned i;
|
||||
Elf_Shdr *s, *sections;
|
||||
Elf_Sym *sym;
|
||||
|
||||
sections = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff));
|
||||
for (i = 0, s = sections;
|
||||
i < grub_target_to_host16 (e->e_shnum);
|
||||
i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize)))
|
||||
if (grub_target_to_host32 (s->sh_type) == SHT_SYMTAB)
|
||||
break;
|
||||
|
||||
if (i == grub_target_to_host16 (e->e_shnum))
|
||||
return NULL;
|
||||
|
||||
sym = (Elf_Sym *) ((char *) e + grub_target_to_host (s->sh_offset));
|
||||
*size = grub_target_to_host (s->sh_size);
|
||||
*entsize = grub_target_to_host (s->sh_entsize);
|
||||
return sym;
|
||||
}
|
||||
|
||||
static int
|
||||
is_whitelisted (const char *modname, const char **whitelist)
|
||||
{
|
||||
const char **ptr;
|
||||
if (!whitelist)
|
||||
return 0;
|
||||
if (!modname)
|
||||
return 0;
|
||||
for (ptr = whitelist; *ptr; ptr++)
|
||||
if (strcmp (modname, *ptr) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
check_symbols (const struct grub_module_verifier_arch *arch,
|
||||
Elf_Ehdr *e, const char *modname,
|
||||
const char **whitelist_empty)
|
||||
{
|
||||
Elf_Sym *sym;
|
||||
Elf_Word size, entsize;
|
||||
unsigned i;
|
||||
|
||||
/* Module without symbol table and without .moddeps section is useless
|
||||
at boot time, so catch it early to prevent build errors */
|
||||
sym = get_symtab (arch, e, &size, &entsize);
|
||||
if (!sym)
|
||||
{
|
||||
Elf_Shdr *s;
|
||||
|
||||
/* However some modules are dependencies-only,
|
||||
e.g. insmod all_video pulls in all video drivers.
|
||||
Some platforms e.g. xen have no video drivers, so
|
||||
the module does nothing. */
|
||||
if (is_whitelisted (modname, whitelist_empty))
|
||||
return;
|
||||
|
||||
s = find_section (arch, e, ".moddeps");
|
||||
|
||||
if (!s)
|
||||
grub_util_error ("%s: no symbol table and no .moddeps section", modname);
|
||||
|
||||
if (!s->sh_size)
|
||||
grub_util_error ("%s: no symbol table and empty .moddeps section", modname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
i < size / entsize;
|
||||
i++, sym = (Elf_Sym *) ((char *) sym + entsize))
|
||||
{
|
||||
unsigned char type = ELF_ST_TYPE (sym->st_info);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case STT_NOTYPE:
|
||||
case STT_OBJECT:
|
||||
case STT_FUNC:
|
||||
case STT_SECTION:
|
||||
case STT_FILE:
|
||||
break;
|
||||
|
||||
default:
|
||||
return grub_util_error ("%s: unknown symbol type `%d'", modname, (int) type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
is_symbol_local(Elf_Sym *sym)
|
||||
{
|
||||
switch (ELF_ST_TYPE (sym->st_info))
|
||||
{
|
||||
case STT_NOTYPE:
|
||||
case STT_OBJECT:
|
||||
if (sym->st_name != 0 && sym->st_shndx == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case STT_FUNC:
|
||||
case STT_SECTION:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
section_check_relocations (const char * const modname,
|
||||
const struct grub_module_verifier_arch *arch, void *ehdr,
|
||||
Elf_Shdr *s, size_t target_seg_size)
|
||||
{
|
||||
Elf_Rel *rel, *max;
|
||||
Elf_Sym *symtab;
|
||||
Elf_Word symtabsize, symtabentsize;
|
||||
|
||||
symtab = get_symtab (arch, ehdr, &symtabsize, &symtabentsize);
|
||||
if (!symtab)
|
||||
grub_util_error ("%s: relocation without symbol table", modname);
|
||||
|
||||
for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)),
|
||||
max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size));
|
||||
rel < max;
|
||||
rel = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_entsize)))
|
||||
{
|
||||
Elf_Sym *sym;
|
||||
unsigned i;
|
||||
|
||||
if (target_seg_size < grub_target_to_host (rel->r_offset))
|
||||
grub_util_error ("%s: reloc offset is out of the segment", modname);
|
||||
|
||||
grub_size_t r_info;
|
||||
if (arch->machine == EM_MIPS && arch->voidp_sizeof == 8)
|
||||
r_info = ((grub_uint64_t) rel->r_info << 32) |
|
||||
(grub_uint32_t) grub_be_to_cpu64 (rel->r_info);
|
||||
else
|
||||
r_info = grub_target_to_host (rel->r_info);
|
||||
|
||||
grub_uint32_t type = ELF_R_TYPE (r_info);
|
||||
|
||||
if (arch->machine == EM_SPARCV9)
|
||||
type &= 0xff;
|
||||
|
||||
for (i = 0; arch->supported_relocations[i] != -1; i++)
|
||||
if (type == arch->supported_relocations[i])
|
||||
break;
|
||||
if (arch->supported_relocations[i] != -1)
|
||||
continue;
|
||||
if (!arch->short_relocations)
|
||||
grub_util_error ("%s: unsupported relocation 0x%x", modname, type);
|
||||
for (i = 0; arch->short_relocations[i] != -1; i++)
|
||||
if (type == arch->short_relocations[i])
|
||||
break;
|
||||
if (arch->short_relocations[i] == -1)
|
||||
grub_util_error ("%s: unsupported relocation 0x%x", modname, type);
|
||||
sym = (Elf_Sym *) ((char *) symtab + symtabentsize * ELF_R_SYM (r_info));
|
||||
|
||||
if (is_symbol_local (sym))
|
||||
continue;
|
||||
grub_util_error ("%s: relocation 0x%x is not module-local", modname, type);
|
||||
}
|
||||
#if defined(MODULEVERIFIER_ELF64)
|
||||
if (arch->machine == EM_AARCH64)
|
||||
{
|
||||
unsigned unmatched_adr_got_page = 0;
|
||||
Elf_Rela *rel2;
|
||||
for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)),
|
||||
max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size));
|
||||
rel < max;
|
||||
rel = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_entsize)))
|
||||
{
|
||||
switch (ELF_R_TYPE (grub_target_to_host (rel->r_info)))
|
||||
{
|
||||
case R_AARCH64_ADR_GOT_PAGE:
|
||||
unmatched_adr_got_page++;
|
||||
for (rel2 = (Elf_Rela *) ((char *) rel + grub_target_to_host (s->sh_entsize));
|
||||
rel2 < (Elf_Rela *) max;
|
||||
rel2 = (Elf_Rela *) ((char *) rel2 + grub_target_to_host (s->sh_entsize)))
|
||||
if (ELF_R_SYM (rel2->r_info)
|
||||
== ELF_R_SYM (rel->r_info)
|
||||
&& ((Elf_Rela *) rel)->r_addend == rel2->r_addend
|
||||
&& ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC)
|
||||
break;
|
||||
if (rel2 >= (Elf_Rela *) max)
|
||||
grub_util_error ("%s: ADR_GOT_PAGE without matching LD64_GOT_LO12_NC", modname);
|
||||
break;
|
||||
case R_AARCH64_LD64_GOT_LO12_NC:
|
||||
if (unmatched_adr_got_page == 0)
|
||||
grub_util_error ("%s: LD64_GOT_LO12_NC without matching ADR_GOT_PAGE", modname);
|
||||
unmatched_adr_got_page--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
check_relocations (const char * const modname,
|
||||
const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
|
||||
{
|
||||
Elf_Shdr *s;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff));
|
||||
i < grub_target_to_host16 (e->e_shnum);
|
||||
i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize)))
|
||||
if (grub_target_to_host32 (s->sh_type) == SHT_REL || grub_target_to_host32 (s->sh_type) == SHT_RELA)
|
||||
{
|
||||
Elf_Shdr *ts;
|
||||
|
||||
if (grub_target_to_host32 (s->sh_type) == SHT_REL && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_REL))
|
||||
grub_util_error ("%s: unsupported SHT_REL", modname);
|
||||
if (grub_target_to_host32 (s->sh_type) == SHT_RELA && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_RELA))
|
||||
grub_util_error ("%s: unsupported SHT_RELA", modname);
|
||||
|
||||
/* Find the target segment. */
|
||||
if (grub_target_to_host32 (s->sh_info) >= grub_target_to_host16 (e->e_shnum))
|
||||
grub_util_error ("%s: orphaned reloc section", modname);
|
||||
ts = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host32 (s->sh_info) * grub_target_to_host16 (e->e_shentsize));
|
||||
|
||||
section_check_relocations (modname, arch, e, s, grub_target_to_host (ts->sh_size));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SUFFIX(grub_module_verify) (const char * const filename,
|
||||
void *module_img, size_t size,
|
||||
const struct grub_module_verifier_arch *arch,
|
||||
const char **whitelist_empty)
|
||||
{
|
||||
Elf_Ehdr *e = module_img;
|
||||
|
||||
/* Check the header size. */
|
||||
if (size < sizeof (Elf_Ehdr))
|
||||
grub_util_error ("%s: ELF header smaller than expected", filename);
|
||||
|
||||
/* Check the magic numbers. */
|
||||
if (e->e_ident[EI_MAG0] != ELFMAG0
|
||||
|| e->e_ident[EI_MAG1] != ELFMAG1
|
||||
|| e->e_ident[EI_MAG2] != ELFMAG2
|
||||
|| e->e_ident[EI_MAG3] != ELFMAG3
|
||||
|| e->e_ident[EI_VERSION] != EV_CURRENT
|
||||
|| grub_target_to_host32 (e->e_version) != EV_CURRENT)
|
||||
grub_util_error ("%s: invalid arch-independent ELF magic", filename);
|
||||
|
||||
if (e->e_ident[EI_CLASS] != ELFCLASSXX
|
||||
|| e->e_ident[EI_DATA] != (arch->bigendian ? ELFDATA2MSB : ELFDATA2LSB)
|
||||
|| grub_target_to_host16 (e->e_machine) != arch->machine)
|
||||
grub_util_error ("%s: invalid arch-dependent ELF magic", filename);
|
||||
|
||||
if (grub_target_to_host16 (e->e_type) != ET_REL)
|
||||
{
|
||||
grub_util_error ("%s: this ELF file is not of the right type", filename);
|
||||
}
|
||||
|
||||
/* Make sure that every section is within the core. */
|
||||
if (size < grub_target_to_host (e->e_shoff)
|
||||
+ (grub_uint32_t) grub_target_to_host16 (e->e_shentsize) * grub_target_to_host16(e->e_shnum))
|
||||
{
|
||||
grub_util_error ("%s: ELF sections outside core", filename);
|
||||
}
|
||||
|
||||
check_license (filename, arch, e);
|
||||
|
||||
Elf_Shdr *s;
|
||||
const char *modname;
|
||||
|
||||
s = find_section (arch, e, ".modname");
|
||||
if (!s)
|
||||
grub_util_error ("%s: no module name found", filename);
|
||||
|
||||
modname = (const char *) e + grub_target_to_host (s->sh_offset);
|
||||
|
||||
check_symbols(arch, e, modname, whitelist_empty);
|
||||
check_relocations(modname, arch, e);
|
||||
}
|
1776
GRUB2/MOD_SRC/grub-2.04/util/mkimage.c
Normal file
1776
GRUB2/MOD_SRC/grub-2.04/util/mkimage.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user