Merge pull request #26641 from medhefgo/boot-elf2efi

boot: Drop gnu-efi / Add elf2efi.py
This commit is contained in:
Yu Watanabe 2023-03-11 17:15:01 +09:00 committed by GitHub
commit c9501b03cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 1389 additions and 717 deletions

View file

@ -9,7 +9,7 @@ success() { echo >&2 -e "\033[32;1m$1\033[0m"; }
ARGS=(
"--optimization=0"
"--optimization=s -Dgnu-efi=true -Defi-cflags=-m32 -Defi-libdir=/usr/lib32"
"--optimization=s"
"--optimization=3 -Db_lto=true -Ddns-over-tls=false"
"--optimization=3 -Db_lto=false"
"--optimization=3 -Ddns-over-tls=openssl"
@ -27,7 +27,6 @@ PACKAGES=(
kbd
libblkid-dev
libbpf-dev
libc6-dev-i386
libcap-dev
libcurl4-gnutls-dev
libfdisk-dev
@ -55,6 +54,7 @@ PACKAGES=(
python3-lxml
python3-pefile
python3-pip
python3-pyelftools
python3-pyparsing
python3-setuptools
quota
@ -156,8 +156,8 @@ for args in "${ARGS[@]}"; do
fatal "'meson compile' failed with '$args'"
fi
for loader in build/src/boot/efi/*.efi; do
if sbverify --list "$loader" |& grep -q "gap in section table"; then
for loader in build/src/boot/efi/*{.efi,.efi.stub}; do
if [[ "$(sbverify --list "$loader" 2>&1)" != "No signature table present" ]]; then
fatal "$loader: Gaps found in section table"
fi
done

View file

@ -22,6 +22,7 @@ ADDITIONAL_DEPS=(
perl
python3-libevdev
python3-pefile
python3-pyelftools
python3-pyparsing
rpm
zstd

2
README
View file

@ -216,7 +216,7 @@ REQUIREMENTS:
awk, sed, grep, and similar tools
clang >= 10.0, llvm >= 10.0 (optional, required to build BPF programs
from source code in C)
gnu-efi >= 3.0.5 (optional, required for systemd-boot)
pyelftools (optional, required for systemd-boot)
During runtime, you need the following additional
dependencies:

View file

@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="bootctl" conditional='HAVE_GNU_EFI'
<refentry id="bootctl" conditional='ENABLE_BOOTLOADER'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>bootctl</title>

View file

@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="loader.conf" conditional='HAVE_GNU_EFI'
<refentry id="loader.conf" conditional='ENABLE_BOOTLOADER'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>loader.conf</title>

View file

@ -5,7 +5,7 @@
# ninja -C build update-man-rules
manpages = [
['binfmt.d', '5', [], 'ENABLE_BINFMT'],
['bootctl', '1', [], 'HAVE_GNU_EFI'],
['bootctl', '1', [], 'ENABLE_BOOTLOADER'],
['bootup', '7', [], ''],
['busctl', '1', [], ''],
['coredump.conf', '5', ['coredump.conf.d'], 'ENABLE_COREDUMP'],
@ -31,7 +31,7 @@ manpages = [
['kernel-command-line', '7', [], ''],
['kernel-install', '8', [], 'ENABLE_KERNEL_INSTALL'],
['libudev', '3', [], ''],
['loader.conf', '5', [], 'HAVE_GNU_EFI'],
['loader.conf', '5', [], 'ENABLE_BOOTLOADER'],
['locale.conf', '5', [], ''],
['localectl', '1', [], 'ENABLE_LOCALED'],
['localtime', '5', [], ''],
@ -877,14 +877,17 @@ manpages = [
['systemd-ask-password', '1', [], ''],
['systemd-backlight@.service', '8', ['systemd-backlight'], 'ENABLE_BACKLIGHT'],
['systemd-binfmt.service', '8', ['systemd-binfmt'], 'ENABLE_BINFMT'],
['systemd-bless-boot-generator', '8', [], 'HAVE_GNU_EFI'],
['systemd-bless-boot.service', '8', ['systemd-bless-boot'], 'HAVE_GNU_EFI'],
['systemd-bless-boot-generator', '8', [], 'ENABLE_BOOTLOADER'],
['systemd-bless-boot.service',
'8',
['systemd-bless-boot'],
'ENABLE_BOOTLOADER'],
['systemd-boot-check-no-failures.service',
'8',
['systemd-boot-check-no-failures'],
''],
['systemd-boot-random-seed.service', '8', [], 'HAVE_GNU_EFI'],
['systemd-boot', '7', ['sd-boot'], 'HAVE_GNU_EFI'],
['systemd-boot-random-seed.service', '8', [], 'ENABLE_BOOTLOADER'],
['systemd-boot', '7', ['sd-boot'], 'ENABLE_BOOTLOADER'],
['systemd-cat', '1', [], ''],
['systemd-cgls', '1', [], ''],
['systemd-cgtop', '1', [], ''],
@ -971,7 +974,7 @@ manpages = [
'systemd-makefs',
'systemd-mkswap@.service'],
''],
['systemd-measure', '1', [], 'HAVE_GNU_EFI'],
['systemd-measure', '1', [], 'ENABLE_BOOTLOADER'],
['systemd-modules-load.service', '8', ['systemd-modules-load'], 'HAVE_KMOD'],
['systemd-mount', '1', ['systemd-umount'], ''],
['systemd-network-generator.service', '8', ['systemd-network-generator'], ''],
@ -992,7 +995,7 @@ manpages = [
'systemd-pcrphase',
'systemd-pcrphase-initrd.service',
'systemd-pcrphase-sysinit.service'],
'HAVE_GNU_EFI'],
'ENABLE_BOOTLOADER'],
['systemd-portabled.service', '8', ['systemd-portabled'], 'ENABLE_PORTABLED'],
['systemd-poweroff.service',
'8',
@ -1027,7 +1030,7 @@ manpages = [
['systemd-stub',
'7',
['linuxaa64.efi.stub', 'linuxia32.efi.stub', 'linuxx64.efi.stub', 'sd-stub'],
'HAVE_GNU_EFI'],
'ENABLE_BOOTLOADER'],
['systemd-suspend.service',
'8',
['systemd-hibernate.service',

View file

@ -3,7 +3,7 @@
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-bless-boot-generator" conditional='HAVE_GNU_EFI'>
<refentry id="systemd-bless-boot-generator" conditional='ENABLE_BOOTLOADER'>
<refentryinfo>
<title>systemd-bless-boot-generator</title>

View file

@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-bless-boot.service" conditional='HAVE_GNU_EFI'
<refentry id="systemd-bless-boot.service" conditional='ENABLE_BOOTLOADER'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>

View file

@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-boot-random-seed.service" conditional='HAVE_GNU_EFI'
<refentry id="systemd-boot-random-seed.service" conditional='ENABLE_BOOTLOADER'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>

View file

@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-boot" conditional='HAVE_GNU_EFI'
<refentry id="systemd-boot" conditional='ENABLE_BOOTLOADER'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>systemd-boot</title>

View file

@ -3,7 +3,7 @@
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-measure" xmlns:xi="http://www.w3.org/2001/XInclude" conditional='HAVE_GNU_EFI'>
<refentry id="systemd-measure" xmlns:xi="http://www.w3.org/2001/XInclude" conditional='ENABLE_BOOTLOADER'>
<refentryinfo>
<title>systemd-measure</title>

View file

@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-pcrphase.service" conditional='HAVE_GNU_EFI'
<refentry id="systemd-pcrphase.service" conditional='ENABLE_BOOTLOADER'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>

View file

@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-stub" conditional='HAVE_GNU_EFI'
<refentry id="systemd-stub" conditional='ENABLE_BOOTLOADER'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>systemd-stub</title>

File diff suppressed because it is too large Load diff

View file

@ -93,7 +93,7 @@ option('ldconfig', type : 'boolean',
option('resolve', type : 'boolean',
description : 'systemd-resolved stack')
option('efi', type : 'boolean',
description : 'enable systemd-boot and bootctl')
description : 'enable EFI support')
option('tpm', type : 'boolean',
description : 'TPM should be used to log events and extend the registers')
option('environment-d', type : 'boolean',
@ -436,18 +436,8 @@ option('glib', type : 'combo', choices : ['auto', 'true', 'false'],
option('dbus', type : 'combo', choices : ['auto', 'true', 'false'],
description : 'libdbus support (for tests only)')
option('gnu-efi', type : 'combo', choices : ['auto', 'true', 'false'],
description : 'gnu-efi support for sd-boot')
option('efi-cflags', type : 'array',
description : 'additional flags for EFI compiler')
# Note that LLD does not support PE/COFF relocations
# https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html
option('efi-ld', type : 'combo', choices : ['auto', 'bfd', 'gold'],
description : 'the linker to use for EFI modules')
option('efi-libdir', type : 'string',
description : 'path to the EFI lib directory')
option('efi-includedir', type : 'string', value : '/usr/include/efi',
description : 'path to the EFI header directory')
option('bootloader', type : 'combo', choices : ['auto', 'true', 'false'],
description : 'sd-boot/stub and userspace tools')
option('sbat-distro', type : 'string', value : 'auto',
description : 'SBAT distribution ID, e.g. fedora, or auto for autodetection')
option('sbat-distro-generation', type : 'integer', value : 1,

View file

@ -139,7 +139,7 @@ if [ ! -f "$BUILDDIR"/build.ninja ] ; then
-D pcre2=true \
-D glib=true \
-D dbus=true \
-D gnu-efi=true \
-D bootloader=true \
-D kernel-install=true \
-D analyze=true \
-D bpf-framework=true \

View file

@ -53,7 +53,6 @@ BuildPackages=
gcc
gettext
git
gnu-efi
gperf
lld
llvm

View file

@ -46,4 +46,5 @@ BuildPackages=
python-docutils
python-jinja
python-lxml
python-pyelftools
python-pytest

View file

@ -59,7 +59,6 @@ BuildPackages=
glibc-devel.i686
glibc-static
glibc-static.i686
gnu-efi-devel
libgcrypt-devel # CentOS Stream 8 libgcrypt-devel doesn't ship a pkg-config file.
libxslt
pam-devel
@ -104,3 +103,4 @@ BuildPackages=
python3*dist(docutils)
python3*dist(jinja2)
python3*dist(lxml)
python3*dist(pyelftools)

View file

@ -91,5 +91,6 @@ BuildPackages=
python3-docutils
python3-jinja2
python3-lxml
python3-pyelftools
python3-pytest
xsltproc

View file

@ -50,7 +50,6 @@ BuildPackages=
docbook-xsl
dwarves
glibc-static
gnu-efi-devel
libcap-static
pam-devel
pkgconfig # pkgconf shim to provide /usr/bin/pkg-config
@ -94,4 +93,5 @@ BuildPackages=
python3dist(docutils)
python3dist(jinja2)
python3dist(lxml)
python3dist(pyelftools)
python3dist(pytest)

View file

@ -94,6 +94,7 @@ BuildPackages=
python3-docutils
python3-Jinja2
python3-lxml
python3-pyelftools
python3-pytest
qrencode-devel
shadow

View file

@ -92,5 +92,6 @@ BuildPackages=
python3-docutils
python3-jinja2
python3-lxml
python3-pyelftools
python3-pytest
xsltproc

View file

@ -31,7 +31,7 @@ items = [['busctl', ''],
['systemd-path', ''],
['systemd-run', ''],
['udevadm', ''],
['bootctl', 'HAVE_GNU_EFI'],
['bootctl', 'ENABLE_BOOTLOADER'],
['coredumpctl', 'ENABLE_COREDUMP'],
['homectl', 'ENABLE_HOMED'],
['hostnamectl', 'ENABLE_HOSTNAMED'],

View file

@ -27,7 +27,7 @@ items = [['_busctl', ''],
['_sd_outputmodes', ''],
['_sd_unit_files', ''],
['_sd_machines', ''],
['_bootctl', 'HAVE_GNU_EFI'],
['_bootctl', 'ENABLE_BOOTLOADER'],
['_coredumpctl', 'ENABLE_COREDUMP'],
['_hostnamectl', 'ENABLE_HOSTNAMED'],
['_localectl', 'ENABLE_LOCALED'],

View file

@ -264,10 +264,11 @@ libbasic = static_library(
basic_sources,
fundamental_sources,
include_directories : basic_includes,
dependencies : [versiondep,
dependencies : [libcap,
libm,
threads,
libcap,
libm],
userspace,
versiondep],
c_args : ['-fvisibility=default'],
build_by_default : false)
@ -283,7 +284,8 @@ libbasic_gcrypt = static_library(
'basic-gcrypt',
basic_gcrypt_sources,
include_directories : basic_includes,
dependencies : [libgcrypt],
dependencies : [libgcrypt,
userspace],
c_args : ['-fvisibility=default'],
build_by_default : false)
@ -299,8 +301,9 @@ libbasic_compress = static_library(
'basic-compress',
basic_compress_sources,
include_directories : basic_includes,
dependencies : [libxz,
dependencies : [liblz4,
libxz,
libzstd,
liblz4],
userspace],
c_args : ['-fvisibility=default'],
build_by_default : false)

View file

@ -21,15 +21,9 @@
#include "shim.h"
#include "ticks.h"
#include "util.h"
#include "version.h"
#include "vmm.h"
#ifndef GNU_EFI_USE_MS_ABI
/* We do not use uefi_call_wrapper() in systemd-boot. As such, we rely on the
* compiler to do the calling convention conversion for us. This is check is
* to make sure the -DGNU_EFI_USE_MS_ABI was passed to the compiler. */
#error systemd-boot requires compilation with GNU_EFI_USE_MS_ABI defined.
#endif
/* Magic string for recognizing our own binaries */
_used_ _section_(".sdmagic") static const char magic[] =
"#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
@ -1966,6 +1960,7 @@ static void config_entry_add_osx(Config *config) {
}
}
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
static EFI_STATUS boot_windows_bitlocker(void) {
_cleanup_free_ EFI_HANDLE *handles = NULL;
size_t n_handles;
@ -2046,6 +2041,7 @@ static EFI_STATUS boot_windows_bitlocker(void) {
return EFI_NOT_FOUND;
}
#endif
static void config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) {
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
@ -2735,8 +2731,3 @@ out:
}
DEFINE_EFI_MAIN_FUNCTION(run, "systemd-boot", /*wait_for_debugger=*/false);
/* Fedora has a heavily patched gnu-efi that supports elf constructors. It calls into _entry instead. */
EFI_STATUS _entry(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table) {
return efi_main(image, system_table);
}

View file

@ -126,7 +126,7 @@ _gnu_printf_(2, 0) _warn_unused_result_ char16_t *xvasprintf_status(EFI_STATUS s
/* inttypes.h is provided by libc instead of the compiler and is not supposed to be used in freestanding
* environments. We could use clang __*_FMT*__ constants for this, bug gcc does not have them. :( */
# if defined(__ILP32__) || defined(__arm__)
# if defined(__ILP32__) || defined(__arm__) || defined(__i386__)
# define PRI64_PREFIX "ll"
# elif defined(__LP64__)
# define PRI64_PREFIX "l"

View file

@ -1,129 +1,61 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
conf.set10('ENABLE_EFI', get_option('efi'))
conf.set10('HAVE_GNU_EFI', false)
efi_config_h_dir = meson.current_build_dir()
if not get_option('efi') or get_option('gnu-efi') == 'false'
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but general efi support is disabled')
endif
if efi_arch != ''
libefitest = static_library(
'efitest',
files(
'bcd.c',
'efi-string.c',
),
build_by_default : false,
include_directories : [
basic_includes,
include_directories('.'),
],
dependencies : userspace)
efitest_base = {
'link_with' : [
libefitest,
libshared,
],
}
tests += [
{
'sources' : files('test-bcd.c'),
'dependencies' : libzstd,
'condition' : 'HAVE_ZSTD',
'base' : efitest_base,
},
{
'sources' : files('test-efi-string.c'),
'base' : efitest_base,
},
]
fuzzers += [
{
'sources' : files('fuzz-bcd.c'),
'base' : efitest_base,
},
{
'sources' : files('fuzz-efi-string.c'),
'base' : efitest_base,
},
{
'sources' : files('fuzz-efi-printf.c'),
'base' : efitest_base,
},
]
endif
if conf.get('ENABLE_BOOTLOADER') != 1
subdir_done()
endif
efi_arch = host_machine.cpu_family()
if efi_arch == 'x86' and '-m64' in get_option('efi-cflags')
efi_arch = 'x86_64'
elif efi_arch == 'x86_64' and '-m32' in get_option('efi-cflags')
efi_arch = 'x86'
endif
efi_arch = {
# host_cc_arch: [efi_arch (see Table 3-2 in UEFI spec), obsolete gnu_efi_inc_arch]
'x86': ['ia32', 'ia32'],
'x86_64': ['x64', 'x86_64'],
'arm': ['arm', 'arm'],
'aarch64': ['aa64', 'aarch64'],
'riscv64': ['riscv64', 'riscv64'],
}.get(efi_arch, [])
efi_incdir = get_option('efi-includedir')
found = false
foreach efi_arch_candidate : efi_arch
efi_archdir = efi_incdir / efi_arch_candidate
if cc.has_header(efi_archdir / 'efibind.h',
args: get_option('efi-cflags'))
found = true
break
endif
endforeach
if not found
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but headers not found or efi arch is unknown')
endif
warning('gnu-efi headers not found or efi arch is unknown, disabling gnu-efi support')
subdir_done()
endif
if not cc.has_header_symbol('efi.h', 'EFI_IMAGE_MACHINE_X64',
args: ['-nostdlib', '-ffreestanding', '-fshort-wchar'] + get_option('efi-cflags'),
include_directories: include_directories(efi_incdir,
efi_archdir))
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but found headers are too old (3.0.5+ required)')
endif
warning('gnu-efi headers are too old (3.0.5+ required), disabling gnu-efi support')
subdir_done()
endif
objcopy = run_command(cc.cmd_array(), '-print-prog-name=objcopy', check: true).stdout().strip()
objcopy_2_38 = find_program('objcopy', version: '>=2.38', required: false)
efi_ld = get_option('efi-ld')
if efi_ld == 'auto'
efi_ld = cc.get_linker_id().split('.')[1]
if efi_ld not in ['bfd', 'gold']
message('Not using @0@ as efi-ld, falling back to bfd'.format(efi_ld))
efi_ld = 'bfd'
endif
endif
efi_multilib = run_command(
cc.cmd_array(), '-print-multi-os-directory', get_option('efi-cflags'),
check: false
).stdout().strip()
efi_multilib = run_command(
'realpath', '-e', '/usr/lib' / efi_multilib,
check: false
).stdout().strip()
efi_libdir = ''
foreach dir : [get_option('efi-libdir'),
'/usr/lib/gnuefi' / efi_arch[0],
efi_multilib]
if dir != '' and fs.is_dir(dir)
efi_libdir = dir
break
endif
endforeach
if efi_libdir == ''
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but efi-libdir was not found')
endif
warning('efi-libdir was not found, disabling gnu-efi support')
subdir_done()
endif
efi_lds = ''
foreach location : [ # New locations first introduced with gnu-efi 3.0.11
[efi_libdir / 'efi.lds',
efi_libdir / 'crt0.o'],
# Older locations...
[efi_libdir / 'gnuefi' / 'elf_@0@_efi.lds'.format(efi_arch[1]),
efi_libdir / 'gnuefi' / 'crt0-efi-@0@.o'.format(efi_arch[1])],
[efi_libdir / 'elf_@0@_efi.lds'.format(efi_arch[1]),
efi_libdir / 'crt0-efi-@0@.o'.format(efi_arch[1])]]
if fs.is_file(location[0]) and fs.is_file(location[1])
efi_lds = location[0]
efi_crt0 = location[1]
break
endif
endforeach
if efi_lds == ''
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but cannot find efi.lds')
endif
warning('efi.lds was not found, disabling gnu-efi support')
subdir_done()
endif
conf.set10('HAVE_GNU_EFI', true)
conf.set_quoted('EFI_MACHINE_TYPE_NAME', efi_arch[0])
efi_conf = configuration_data()
efi_conf.set_quoted('EFI_MACHINE_TYPE_NAME', efi_arch[0])
efi_conf.set10('ENABLE_TPM', get_option('tpm'))
foreach ctype : ['color-normal', 'color-entry', 'color-highlight', 'color-edit']
@ -174,151 +106,8 @@ elif get_option('sbat-distro') != ''
endif
endif
efi_config_h = configure_file(
output : 'efi_config.h',
configuration : efi_conf)
efi_cflags = [
'-DGNU_EFI_USE_MS_ABI',
'-DSD_BOOT=1',
'-ffreestanding',
'-fshort-wchar',
'-fvisibility=hidden',
'-I', fundamental_path,
'-I', meson.current_source_dir(),
'-include', efi_config_h,
'-include', version_h,
'-std=gnu11',
'-Wall',
'-Wextra',
] + cc.get_supported_arguments(
basic_disabled_warnings +
possible_common_cc_flags + [
'-fno-stack-protector',
'-fno-strict-aliasing',
'-fpic',
'-fwide-exec-charset=UCS2',
]
)
efi_cflags += cc.get_supported_arguments({
'ia32': ['-mno-sse', '-mno-mmx'],
'x86_64': ['-mno-red-zone', '-mno-sse', '-mno-mmx'],
'arm': ['-mgeneral-regs-only', '-mfpu=none'],
}.get(efi_arch[1], []))
# We are putting the efi_cc command line together ourselves, so make sure to pull any
# relevant compiler flags from meson/CFLAGS as povided by the user or distro.
if get_option('werror')
efi_cflags += ['-Werror']
endif
if get_option('debug') and get_option('mode') == 'developer'
efi_cflags += ['-ggdb', '-DEFI_DEBUG']
endif
if get_option('optimization') in ['1', '2', '3', 's', 'g']
efi_cflags += ['-O' + get_option('optimization')]
endif
if get_option('b_ndebug') == 'true' or (
get_option('b_ndebug') == 'if-release' and get_option('buildtype') in ['plain', 'release'])
efi_cflags += ['-DNDEBUG']
endif
if get_option('b_lto')
efi_cflags += cc.has_argument('-flto=auto') ? ['-flto=auto'] : ['-flto']
endif
foreach arg : get_option('c_args')
if arg in [
'-DNDEBUG',
'-fno-lto',
'-O1', '-O2', '-O3', '-Og', '-Os',
'-Werror',
] or arg.split('=')[0] in [
'-ffile-prefix-map',
'-flto',
] or (get_option('mode') == 'developer' and arg in [
'-DEFI_DEBUG',
'-g', '-ggdb',
])
message('Using "@0@" from c_args for EFI compiler'.format(arg))
efi_cflags += arg
endif
endforeach
efi_cflags += get_option('efi-cflags')
efi_ldflags = [
'-fuse-ld=' + efi_ld,
'-L', efi_libdir,
'-nostdlib',
'-T', efi_lds,
'-Wl,--build-id=sha1',
'-Wl,--fatal-warnings',
'-Wl,--no-undefined',
'-Wl,--warn-common',
'-Wl,-Bsymbolic',
'-z', 'nocombreloc',
'-z', 'noexecstack',
efi_crt0,
]
foreach arg : ['-Wl,--no-warn-execstack',
'-Wl,--no-warn-rwx-segments']
# We need to check the correct linker for supported args. This is what
# cc.has_multi_link_arguments() is for, but it helpfully overrides our
# choice of linker by putting its own -fuse-ld= arg after ours.
if run_command('bash', '-c',
'exec "$@" -x c -o/dev/null <(echo "int main(void){return 0;}")' +
' -fuse-ld=' + efi_ld + ' -Wl,--fatal-warnings ' + arg,
'bash', cc.cmd_array(),
check : false).returncode() == 0
efi_ldflags += arg
endif
endforeach
# If using objcopy, crt0 must not include the PE/COFF header
if run_command('grep', '-q', 'coff_header', efi_crt0, check: false).returncode() == 0
coff_header_in_crt0 = true
else
coff_header_in_crt0 = false
endif
if efi_arch[1] in ['arm', 'riscv64'] or (efi_arch[1] == 'aarch64' and (not objcopy_2_38.found() or coff_header_in_crt0))
efi_ldflags += ['-shared']
# ARM32 and 64bit RISC-V don't have an EFI capable objcopy.
# Older objcopy doesn't support Aarch64 either.
# Use 'binary' instead, and add required symbols manually.
efi_ldflags += ['-Wl,--defsym=EFI_SUBSYSTEM=0xa']
efi_format = ['-O', 'binary']
else
efi_ldflags += ['-pie']
if efi_ld == 'bfd'
efi_ldflags += '-Wl,--no-dynamic-linker'
endif
efi_format = ['--target=efi-app-@0@'.format(efi_arch[1])]
endif
if efi_arch[1] == 'arm'
# On arm, the compiler (correctly) warns about wchar_t size mismatch. This
# is because libgcc is not compiled with -fshort-wchar, but it does not
# have any occurrences of wchar_t in its sources or the documentation, so
# it is safe to assume that we can ignore this warning.
efi_ldflags += ['-Wl,--no-wchar-size-warning']
endif
if cc.get_id() == 'clang' and cc.version().split('.')[0].to_int() <= 10
# clang <= 10 doesn't pass -T to the linker and then even complains about it being unused
efi_ldflags += ['-Wl,-T,' + efi_lds, '-Wno-unused-command-line-argument']
endif
summary({
'EFI machine type' : efi_arch[0],
'EFI LD' : efi_ld,
'EFI lds' : efi_lds,
'EFI crt0' : efi_crt0,
'EFI include directory' : efi_archdir},
section : 'Extensible Firmware Interface')
summary({'UEFI architectures' : efi_arch + (efi_arch_alt == '' ? '' : ', ' + efi_arch_alt)},
section : 'UEFI')
if efi_conf.get('SBAT_DISTRO', '') != ''
summary({
@ -327,49 +116,114 @@ if efi_conf.get('SBAT_DISTRO', '') != ''
'SBAT distro version': sbat_distro_version_display,
'SBAT distro summary': efi_conf.get('SBAT_DISTRO_SUMMARY'),
'SBAT distro URL': efi_conf.get('SBAT_DISTRO_URL')},
section : 'Extensible Firmware Interface')
section : 'UEFI')
endif
configure_file(
output : 'efi_config.h',
configuration : efi_conf)
############################################################
efi_includes = [fundamental_include, include_directories('.')]
efi_c_args = [
'-DSD_BOOT=1',
'-ffreestanding',
'-fno-strict-aliasing',
'-fshort-wchar',
'-include', 'efi_config.h',
]
efi_c_args += cc.get_supported_arguments(
'-fwide-exec-charset=UCS2',
# gcc docs says this is required for ms_abi to work correctly.
'-maccumulate-outgoing-args',
)
# Debug information has little value in release builds as no normal human being knows
# how to attach a debugger to EFI binaries running on real hardware. Anyone who does
# certainly has the means to do their own dev build.
if get_option('mode') == 'developer' and get_option('debug')
efi_c_args += '-DEFI_DEBUG'
endif
efi_c_ld_args = [
# We only support bfd. gold is going away, lld has issues with LTO on x86
# and mold does not support linker scripts.
'-fuse-ld=bfd',
'-lgcc',
'-nostdlib',
'-static-pie',
'-Wl,--entry=efi_main',
'-Wl,--fatal-warnings',
# These flags should be passed by -static-pie, but seem to be missing sometimes.
'-Wl,--no-dynamic-linker',
'-z', 'text',
# EFI has 4KiB pages.
'-z', 'common-page-size=4096',
'-z', 'max-page-size=4096',
'-z', 'noexecstack',
'-z', 'norelro',
'-T' + elf2efi_lds,
]
# efi_c_args is explicitly passed to targets so that they can override distro-provided flags
# that should not be used for EFI binaries.
efi_disabled_c_args = cc.get_supported_arguments(
'-fcf-protection=none',
'-fno-asynchronous-unwind-tables',
'-fno-exceptions',
'-fno-trapv',
'-fno-sanitize=all',
'-fno-stack-clash-protection',
'-fno-stack-protector',
'-fno-unwind-tables',
)
efi_c_args += efi_disabled_c_args
efi_c_ld_args += efi_disabled_c_args
efi_override_options = [
'b_coverage=false',
'b_pgo=off',
'b_sanitize=none',
]
if cc.get_id() == 'clang'
# clang is too picky sometimes.
efi_c_args += '-Wno-unused-command-line-argument'
efi_c_ld_args += '-Wno-unused-command-line-argument'
endif
if host_machine.cpu_family() == 'arm'
# libgcc is not compiled with -fshort-wchar, but it does not use it anyways,
# so it's fine to link against it.
efi_c_ld_args += '-Wl,--no-wchar-size-warning'
endif
efi_c_args_primary = [efi_c_args, '-DEFI_MACHINE_TYPE_NAME="' + efi_arch + '"']
efi_c_args_alt = [efi_c_args, '-DEFI_MACHINE_TYPE_NAME="' + efi_arch_alt + '"']
efi_c_ld_args_primary = efi_c_ld_args
efi_c_ld_args_alt = efi_c_ld_args
efi_c_args_primary += {
'aarch64' : ['-mgeneral-regs-only'],
'arm' : ['-mgeneral-regs-only'],
'x86_64' : ['-march=x86-64', '-mno-red-zone', '-mgeneral-regs-only'],
'x86' : ['-march=i686', '-mgeneral-regs-only'],
}.get(host_machine.cpu_family(), [])
if efi_arch_alt == 'ia32'
efi_c_args_alt += ['-m32', '-march=i686', '-mgeneral-regs-only']
efi_c_ld_args_alt += '-m32'
endif
############################################################
efi_headers = files(
'bcd.h',
'console.h',
'cpio.h',
'device-path-util.h',
'devicetree.h',
'drivers.h',
'efi-string.h',
'efi.h',
'graphics.h',
'initrd.h',
'linux.h',
'log.h',
'measure.h',
'part-discovery.h',
'pe.h',
'proto/block-io.h',
'proto/console-control.h',
'proto/device-path.h',
'proto/dt-fixup.h',
'proto/file-io.h',
'proto/graphics-output.h',
'proto/load-file.h',
'proto/loaded-image.h',
'proto/rng.h',
'proto/security-arch.h',
'proto/shell-parameters.h',
'proto/simple-text-io.h',
'proto/tcg.h',
'random-seed.h',
'secure-boot.h',
'shim.h',
'splash.h',
'ticks.h',
'util.h',
)
common_sources = files(
libefi_sources = files(
'console.c',
'device-path-util.c',
'devicetree.c',
@ -400,111 +254,94 @@ stub_sources = files(
'stub.c',
)
if efi_arch[1] in ['ia32', 'x86_64']
if host_machine.cpu_family() in ['x86', 'x86_64']
stub_sources += files('linux_x86.c')
endif
tests += [
{
'sources' : files(
'test-efi-string.c',
'efi-string.c',
)
},
]
# BCD parser only makes sense on arches that Windows supports.
if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64']
if host_machine.cpu_family() in ['aarch64', 'arm', 'x86_64', 'x86']
systemd_boot_sources += files('bcd.c')
tests += [
{
'sources' : files(
'test-bcd.c',
'efi-string.c',
),
'dependencies' : libzstd,
'condition' : 'HAVE_ZSTD',
},
]
fuzzers += [
{
'sources' : files(
'fuzz-bcd.c',
'bcd.c',
'efi-string.c'
),
},
{
'sources' : files(
'fuzz-efi-string.c',
'efi-string.c'
),
},
{
'sources' : files(
'fuzz-efi-printf.c',
'efi-string.c'
),
},
]
endif
systemd_boot_objects = []
stub_objects = []
foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources
# FIXME: replace ''.format(file) with fs.name(file) when meson_version requirement is >= 0.59.0
o_file = custom_target('@0@.o'.format(file).split('/')[-1],
input : file,
output : '@0@.o'.format(file).split('/')[-1],
command : [cc.cmd_array(), '-c', '@INPUT@', '-o', '@OUTPUT@', efi_cflags],
depend_files : efi_headers + fundamental_headers)
if (fundamental_source_paths + common_sources + systemd_boot_sources).contains(file)
systemd_boot_objects += o_file
endif
if (fundamental_source_paths + common_sources + stub_sources).contains(file)
stub_objects += o_file
endif
boot_targets = []
efi_elf_binaries = []
efi_archspecs = [
{
'arch' : efi_arch,
'c_args' : efi_c_args_primary,
'link_args' : efi_c_ld_args_primary,
},
]
if efi_arch_alt != ''
efi_archspecs += {
'arch' : efi_arch_alt,
'c_args' : efi_c_args_alt,
'link_args' : efi_c_ld_args_alt,
}
endif
foreach archspec : efi_archspecs
libefi = static_library(
'efi' + archspec['arch'],
fundamental_sources,
libefi_sources,
include_directories : efi_includes,
c_args : archspec['c_args'],
dependencies : versiondep,
gnu_symbol_visibility : 'hidden',
override_options : efi_override_options,
pic : true)
efi_elf_binaries += executable(
'systemd-boot' + archspec['arch'],
systemd_boot_sources,
include_directories : efi_includes,
c_args : archspec['c_args'],
link_args : archspec['link_args'],
link_with : libefi,
link_depends : elf2efi_lds,
dependencies : versiondep,
gnu_symbol_visibility : 'hidden',
override_options : efi_override_options,
name_suffix : 'elf',
pie : true)
efi_elf_binaries += executable(
'linux' + archspec['arch'],
stub_sources,
include_directories : efi_includes,
c_args : archspec['c_args'],
link_args : archspec['link_args'],
link_with : libefi,
link_depends : elf2efi_lds,
dependencies : versiondep,
gnu_symbol_visibility : 'hidden',
override_options : efi_override_options,
name_suffix : 'elf.stub',
pie : true)
endforeach
foreach tuple : [['systemd-boot@0@.@1@', systemd_boot_objects, false, 'systemd-boot'],
['linux@0@.@1@.stub', stub_objects, true, 'systemd-stub']]
elf = custom_target(
tuple[0].format(efi_arch[0], 'elf'),
input : tuple[1],
output : tuple[0].format(efi_arch[0], 'elf'),
command : [cc.cmd_array(),
'-o', '@OUTPUT@',
efi_cflags,
efi_ldflags,
'@INPUT@',
'-lgnuefi',
'-lgcc'],
install : tuple[2],
install_tag: tuple[3],
install_dir : bootlibdir)
efi = custom_target(
tuple[0].format(efi_arch[0], 'efi'),
input : elf,
output : tuple[0].format(efi_arch[0], 'efi'),
command : [objcopy,
'-j', '.bss*',
'-j', '.data',
'-j', '.dynamic',
'-j', '.dynsym',
'-j', '.osrel',
'-j', '.rel*',
'-j', '.sbat',
'-j', '.sdata',
'-j', '.sdmagic',
'-j', '.text',
'--strip-all',
'--section-alignment=512',
efi_format,
'@INPUT@', '@OUTPUT@'],
foreach efi_elf_binary : efi_elf_binaries
# FIXME: Use build_tgt.name() with meson >= 0.54.0
name = fs.name(efi_elf_binary.full_path()).split('.')[0]
name += name.startswith('linux') ? '.efi.stub' : '.efi'
boot_targets += custom_target(
name,
output : name,
input : efi_elf_binary,
install : true,
install_tag: tuple[3],
install_dir : bootlibdir)
alias_target(tuple[3], efi)
install_dir : bootlibdir,
install_tag : 'systemd-boot',
command : [
elf2efi_py,
'--version-major=' + meson.project_version(),
'--version-minor=0',
'--efi-major=1',
'--efi-minor=1',
'--subsystem=10',
'@INPUT@',
'@OUTPUT@',
])
endforeach
alias_target('systemd-boot', boot_targets)

View file

@ -16,8 +16,14 @@
# define TARGET_MACHINE_TYPE 0xAA64U
#elif defined(__arm__)
# define TARGET_MACHINE_TYPE 0x01C2U
#elif defined(__riscv) && __riscv_xlen == 32
# define TARGET_MACHINE_TYPE 0x5032U
#elif defined(__riscv) && __riscv_xlen == 64
# define TARGET_MACHINE_TYPE 0x5064U
#elif defined(__loongarch__) && __loongarch_grlen == 32
# define TARGET_MACHINE_TYPE 0x6232U
#elif defined(__loongarch__) && __loongarch_grlen == 64
# define TARGET_MACHINE_TYPE 0x6264U
#else
# error Unknown EFI arch
#endif

View file

@ -14,6 +14,7 @@
#include "splash.h"
#include "tpm-pcr.h"
#include "util.h"
#include "version.h"
#include "vmm.h"
/* magic string to find in the binary image */
@ -423,8 +424,3 @@ static EFI_STATUS run(EFI_HANDLE image) {
}
DEFINE_EFI_MAIN_FUNCTION(run, "systemd-stub", /*wait_for_debugger=*/false);
/* See comment in boot.c. */
EFI_STATUS _entry(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table) {
return efi_main(image, system_table);
}

View file

@ -508,9 +508,9 @@ uint64_t get_os_indications_supported(void) {
}
#ifdef EFI_DEBUG
extern uint8_t _text, _data;
extern uint8_t __ImageBase;
__attribute__((noinline)) void notify_debugger(const char *identity, volatile bool wait) {
printf("%s@%p,%p\n", identity, &_text, &_data);
printf("%s@%p\n", identity, &__ImageBase);
if (wait)
printf("Waiting for debugger to attach...\n");

View file

@ -168,18 +168,18 @@ void hexdump(const char16_t *prefix, const void *data, size_t size);
# define notify_debugger(i, w)
#endif
#define DEFINE_EFI_MAIN_FUNCTION(func, identity, wait_for_debugger) \
EFI_SYSTEM_TABLE *ST; \
EFI_BOOT_SERVICES *BS; \
EFI_RUNTIME_SERVICES *RT; \
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table) { \
ST = system_table; \
BS = system_table->BootServices; \
RT = system_table->RuntimeServices; \
notify_debugger((identity), (wait_for_debugger)); \
EFI_STATUS err = func(image); \
log_wait(); \
return err; \
#define DEFINE_EFI_MAIN_FUNCTION(func, identity, wait_for_debugger) \
EFI_SYSTEM_TABLE *ST; \
EFI_BOOT_SERVICES *BS; \
EFI_RUNTIME_SERVICES *RT; \
EFIAPI EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table) { \
ST = system_table; \
BS = system_table->BootServices; \
RT = system_table->RuntimeServices; \
notify_debugger((identity), (wait_for_debugger)); \
EFI_STATUS err = func(image); \
log_wait(); \
return err; \
}
#if defined(__i386__) || defined(__x86_64__)

View file

@ -120,19 +120,20 @@ libcore = shared_library(
link_args : ['-shared',
'-Wl,--version-script=' + libshared_sym_path],
link_with : libshared,
dependencies : [versiondep,
threads,
dependencies : [libacl,
libapparmor,
libaudit,
libblkid,
libdl,
libkmod,
libmount,
libpam,
librt,
libseccomp,
libpam,
libaudit,
libkmod,
libapparmor,
libselinux,
libmount,
libblkid,
libacl],
threads,
userspace,
versiondep],
install : true,
install_dir : rootpkglibdir)

View file

@ -7,6 +7,7 @@ lib_cryptsetup_token_common = static_library(
'cryptsetup-token-common',
'cryptsetup-token-util.c',
include_directories : includes,
dependencies : userspace,
link_with : libshared,
build_by_default : false)

View file

@ -1,25 +1,11 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
fundamental_path = meson.current_source_dir()
fundamental_include = include_directories('.')
fundamental_headers = files(
'bootspec-fundamental.h',
'efivars-fundamental.h',
'macro-fundamental.h',
'memory-util-fundamental.h',
'sha256.h',
'string-util-fundamental.h',
'tpm-pcr.h',
)
# for sd-boot
fundamental_source_paths = files(
fundamental_sources = files(
'bootspec-fundamental.c',
'efivars-fundamental.c',
'sha256.c',
'string-util-fundamental.c',
'tpm-pcr.c',
)
# for libbasic
fundamental_sources = fundamental_source_paths + fundamental_headers

View file

@ -1,5 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "version.h"
#ifdef SBAT_DISTRO
# define SBAT_SECTION_TEXT \
"sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md\n" \

View file

@ -36,7 +36,8 @@ if conf.get('ENABLE_IMPORTD') == 1
include_directories : includes,
dependencies : [libbzip2,
libxz,
libz],
libz,
userspace],
build_by_default : false)
install_data('org.freedesktop.import1.conf',

View file

@ -22,11 +22,12 @@ libsystemd_journal_remote = static_library(
libsystemd_journal_remote_sources,
include_directories : journal_includes,
link_with : libjournal_core,
dependencies : [threads,
dependencies : [libgnutls,
liblz4,
libmicrohttpd,
libgnutls,
libxz,
liblz4],
threads,
userspace],
build_by_default : false)
systemd_journal_remote_sources = files('journal-remote-main.c')

View file

@ -25,7 +25,8 @@ libjournal_core = static_library(
'journal-core',
sources,
include_directories : includes,
dependencies: threads,
dependencies: [threads,
userspace],
build_by_default : false)
journal_includes = [includes, include_directories('.')]

View file

@ -32,6 +32,7 @@ libsystemd_network = static_library(
'systemd-network',
sources,
include_directories : includes,
dependencies : userspace,
build_by_default : false)
libsystemd_network_includes = [includes, include_directories('.')]

View file

@ -122,7 +122,8 @@ libsystemd_static = static_library(
link_with : [libbasic,
libbasic_compress],
dependencies : [threads,
librt],
librt,
userspace],
build_by_default : false)
libsystemd_sym = files('libsystemd.sym')

View file

@ -25,6 +25,7 @@ libudev_basic = static_library(
'udev-basic',
libudev_sources,
include_directories : includes,
dependencies : userspace,
c_args : ['-fvisibility=default'],
build_by_default : false)

View file

@ -35,7 +35,8 @@ liblogind_core = static_library(
'logind-core',
liblogind_core_sources,
include_directories : includes,
dependencies : libacl,
dependencies : [libacl,
userspace],
build_by_default : false)
loginctl_sources = files(

View file

@ -18,7 +18,8 @@ libmachine_core = static_library(
'machine-core',
libmachine_core_sources,
include_directories : includes,
dependencies : threads,
dependencies : [threads,
userspace],
build_by_default : false)
if conf.get('ENABLE_MACHINED') == 1

View file

@ -146,6 +146,7 @@ libnetworkd_core = static_library(
'networkd-core',
sources,
include_directories : network_includes,
dependencies : userspace,
link_with : networkd_link_with,
build_by_default : false)

View file

@ -31,7 +31,8 @@ libnspawn_core = static_library(
include_directories : includes,
dependencies : [libacl,
libseccomp,
libselinux],
libselinux,
userspace],
build_by_default : false)
systemd_nspawn_sources = files('nspawn.c')

View file

@ -85,6 +85,7 @@ libsystemd_resolve_core = static_library(
'systemd-resolve-core',
basic_dns_sources,
include_directories : includes,
dependencies : userspace,
build_by_default : false)
systemd_resolved_sources += custom_target(

View file

@ -296,7 +296,8 @@ libshared_static = static_library(
libshared_name,
shared_sources,
include_directories : includes,
dependencies : libshared_deps,
dependencies : [libshared_deps,
userspace],
c_args : ['-fvisibility=default'],
build_by_default : false)
@ -310,7 +311,8 @@ libshared = shared_library(
libbasic,
libbasic_gcrypt,
libsystemd_static],
dependencies : libshared_deps,
dependencies : [libshared_deps,
userspace],
install : true,
install_dir : rootpkglibdir)
@ -323,7 +325,8 @@ if get_option('fdisk') != 'false'
'shared-fdisk',
shared_fdisk_sources,
include_directories : includes,
dependencies : [libfdisk],
dependencies : [libfdisk,
userspace],
c_args : ['-fvisibility=default'],
build_by_default : false)
endif

View file

@ -456,7 +456,7 @@ tests += [
},
{
'sources' : files('test-sbat.c'),
'condition' : 'HAVE_GNU_EFI',
'condition' : 'ENABLE_BOOTLOADER',
'c_args' : '-I@0@'.format(efi_config_h_dir),
},
{

View file

@ -29,6 +29,7 @@ libtimesyncd_core = static_library(
'timesyncd-core',
sources,
include_directories : includes,
dependencies : userspace,
link_with : timesyncd_link_with,
build_by_default : false)

View file

@ -108,7 +108,8 @@ libudevd_core = static_library(
include_directories : udev_includes,
link_with : udev_link_with,
dependencies : [libblkid,
libkmod],
libkmod,
userspace],
build_by_default : false)
udev_progs = [['ata_id/ata_id.c'],
@ -134,7 +135,8 @@ foreach prog : udev_progs
name,
prog,
include_directories : includes,
dependencies : versiondep,
dependencies : [userspace,
versiondep],
link_with : udev_link_with,
install_rpath : udev_rpath,
install : true,

View file

@ -73,7 +73,7 @@ if install_tests
'../-.mount',
testsuite08_dir + '/local-fs.target.wants/-.mount')
if conf.get('HAVE_GNU_EFI') == 1 and conf.get('HAVE_ZSTD') == 1
if conf.get('HAVE_ZSTD') == 1 and efi_arch != ''
install_subdir('test-bcd',
exclude_files : '.gitattributes',
install_dir : testdata_dir)

View file

@ -33,8 +33,6 @@ BuildPackages=
gcc
gettext
git
gnu-efi
gnu-efi-devel
gnutls-devel
gperf
hostname

View file

@ -51,19 +51,17 @@ case "${BASH_REMATCH[1]}" in
exit 1
esac
# system-boot will print out a line like this to inform us where gdb is supposed to
# look for .text and .data section:
# systemd-boot@0x0,0x0
# system-boot/stub will print out a line like this to inform us where it was loaded:
# systemd-boot@0xC0DE
while read -r line; do
if [[ "${line}" =~ ${target}@(0x[[:xdigit:]]+),(0x[[:xdigit:]]+) ]]; then
text="${BASH_REMATCH[1]}"
data="${BASH_REMATCH[2]}"
if [[ "${line}" =~ ${target}@(0x[[:xdigit:]]+) ]]; then
loaded_base="${BASH_REMATCH[1]}"
break
fi
done <"${2}"
if [[ -z "${text}" || -z "${data}" ]]; then
echo "Could not determine text and data location."
if [[ -z "${loaded_base}" ]]; then
echo "Could not determine loaded image base."
exit 1
fi
@ -76,8 +74,8 @@ fi
cat >"${gdb_script}" <<EOF
file ${binary}
add-symbol-file ${symbols} ${text} -s .data ${data}
set architecture ${arch}"
symbol-file ${symbols} -o ${loaded_base}
set architecture ${arch}
EOF
if [[ -z "${3}" ]]; then

51
tools/elf2efi.lds Normal file
View file

@ -0,0 +1,51 @@
SECTIONS {
__ImageBase = .;
/* We skip the first page because the space will be occupied by the PE headers after conversion. */
. = CONSTANT(MAXPAGESIZE);
.text ALIGN(CONSTANT(MAXPAGESIZE)) : {
*(.text .text.*)
}
.rodata ALIGN(CONSTANT(MAXPAGESIZE)) : {
*(.rodata .rodata.*)
*(.srodata .srodata.*)
}
.data ALIGN(CONSTANT(MAXPAGESIZE)) : {
*(.data .data.*)
*(.sdata .sdata.*)
*(.got .got.*)
*(.got.plt .got.plt.*)
/* EDK2 says some firmware cannot handle BSS sections properly. */
*(.bss .bss.*)
*(.sbss .sbss.*)
*(COMMON)
}
.sdmagic ALIGN(CONSTANT(MAXPAGESIZE)) : { *(.sdmagic) }
.osrel ALIGN(CONSTANT(MAXPAGESIZE)) : { *(.osrel) }
.sbat ALIGN(CONSTANT(MAXPAGESIZE)) : { *(.sbat) }
/* These are used for PE conversion and then discarded. */
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.dynamic : { *(.dynamic) }
.rel.dyn : { *(.rel.dyn) }
.rela.dyn : { *(.rela.dyn) }
/* These aren't needed and could be discarded. Just in case that they're useful to the debugger
* we keep them, but move them out of the way to keep the PE binary more compact. */
.ARM.exidx : { *(.ARM.exidx) }
.eh_frame : { *(.eh_frame) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
.gnu.hash : { *(.gnu.hash) }
.hash : { *(.hash) }
.note.gnu.build-id : { *(.note.gnu.build-id ) }
/DISCARD/ : {
*(.ARM.attributes)
*(.comment)
*(.note.*)
*(.riscv.attributes)
}
}

581
tools/elf2efi.py Executable file
View file

@ -0,0 +1,581 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1-or-later
# Convert ELF static PIE to PE/EFI image.
# To do so we simply copy desired ELF sections while preserving their memory layout to ensure that
# code still runs as expected. We then translate ELF relocations to PE relocations so that the EFI
# loader/firmware can properly load the binary to any address at runtime.
#
# To make this as painless as possible we only operate on static PIEs as they should only contain
# base relocations that are easy to handle as they have a one-to-one mapping to PE relocations.
#
# EDK2 does a similar process using their GenFw tool. The main difference is that they use the
# --emit-relocs linker flag, which emits a lot of different (static) ELF relocation types that have
# to be handled differently for each architecture and is overall more work than its worth.
#
# Note that on arches where binutils has PE support (x86/x86_64 mostly, aarch64 only recently)
# objcopy can be used to convert ELF to PE. But this will still not convert ELF relocations, making
# the resulting binary useless. gnu-efi relies on this method and contains a stub that performs the
# ELF dynamic relocations at runtime.
# pylint: disable=missing-docstring,invalid-name,attribute-defined-outside-init
import argparse
import hashlib
import io
import os
import pathlib
import time
from ctypes import (
c_char,
c_uint8,
c_uint16,
c_uint32,
c_uint64,
LittleEndianStructure,
sizeof,
)
from elftools.elf.constants import SH_FLAGS
from elftools.elf.elffile import ELFFile, Section as ELFSection
from elftools.elf.enums import (
ENUM_DT_FLAGS_1,
ENUM_RELOC_TYPE_AARCH64,
ENUM_RELOC_TYPE_ARM,
ENUM_RELOC_TYPE_i386,
ENUM_RELOC_TYPE_x64,
)
from elftools.elf.relocation import (
Relocation as ElfRelocation,
RelocationTable as ElfRelocationTable,
)
class PeCoffHeader(LittleEndianStructure):
_fields_ = (
("Machine", c_uint16),
("NumberOfSections", c_uint16),
("TimeDateStamp", c_uint32),
("PointerToSymbolTable", c_uint32),
("NumberOfSymbols", c_uint32),
("SizeOfOptionalHeader", c_uint16),
("Characteristics", c_uint16),
)
class PeDataDirectory(LittleEndianStructure):
_fields_ = (
("VirtualAddress", c_uint32),
("Size", c_uint32),
)
class PeRelocationBlock(LittleEndianStructure):
_fields_ = (
("PageRVA", c_uint32),
("BlockSize", c_uint32),
)
def __init__(self, PageRVA: int):
super().__init__(PageRVA)
self.entries: list[PeRelocationEntry] = []
class PeRelocationEntry(LittleEndianStructure):
_fields_ = (
("Offset", c_uint16, 12),
("Type", c_uint16, 4),
)
class PeOptionalHeaderStart(LittleEndianStructure):
_fields_ = (
("Magic", c_uint16),
("MajorLinkerVersion", c_uint8),
("MinorLinkerVersion", c_uint8),
("SizeOfCode", c_uint32),
("SizeOfInitializedData", c_uint32),
("SizeOfUninitializedData", c_uint32),
("AddressOfEntryPoint", c_uint32),
("BaseOfCode", c_uint32),
)
class PeOptionalHeaderMiddle(LittleEndianStructure):
_fields_ = (
("SectionAlignment", c_uint32),
("FileAlignment", c_uint32),
("MajorOperatingSystemVersion", c_uint16),
("MinorOperatingSystemVersion", c_uint16),
("MajorImageVersion", c_uint16),
("MinorImageVersion", c_uint16),
("MajorSubsystemVersion", c_uint16),
("MinorSubsystemVersion", c_uint16),
("Win32VersionValue", c_uint32),
("SizeOfImage", c_uint32),
("SizeOfHeaders", c_uint32),
("CheckSum", c_uint32),
("Subsystem", c_uint16),
("DllCharacteristics", c_uint16),
)
class PeOptionalHeaderEnd(LittleEndianStructure):
_fields_ = (
("LoaderFlags", c_uint32),
("NumberOfRvaAndSizes", c_uint32),
("ExportTable", PeDataDirectory),
("ImportTable", PeDataDirectory),
("ResourceTable", PeDataDirectory),
("ExceptionTable", PeDataDirectory),
("CertificateTable", PeDataDirectory),
("BaseRelocationTable", PeDataDirectory),
("Debug", PeDataDirectory),
("Architecture", PeDataDirectory),
("GlobalPtr", PeDataDirectory),
("TLSTable", PeDataDirectory),
("LoadConfigTable", PeDataDirectory),
("BoundImport", PeDataDirectory),
("IAT", PeDataDirectory),
("DelayImportDescriptor", PeDataDirectory),
("CLRRuntimeHeader", PeDataDirectory),
("Reserved", PeDataDirectory),
)
class PeOptionalHeader(LittleEndianStructure):
pass
class PeOptionalHeader32(PeOptionalHeader):
_anonymous_ = ("Start", "Middle", "End")
_fields_ = (
("Start", PeOptionalHeaderStart),
("BaseOfData", c_uint32),
("ImageBase", c_uint32),
("Middle", PeOptionalHeaderMiddle),
("SizeOfStackReserve", c_uint32),
("SizeOfStackCommit", c_uint32),
("SizeOfHeapReserve", c_uint32),
("SizeOfHeapCommit", c_uint32),
("End", PeOptionalHeaderEnd),
)
class PeOptionalHeader32Plus(PeOptionalHeader):
_anonymous_ = ("Start", "Middle", "End")
_fields_ = (
("Start", PeOptionalHeaderStart),
("ImageBase", c_uint64),
("Middle", PeOptionalHeaderMiddle),
("SizeOfStackReserve", c_uint64),
("SizeOfStackCommit", c_uint64),
("SizeOfHeapReserve", c_uint64),
("SizeOfHeapCommit", c_uint64),
("End", PeOptionalHeaderEnd),
)
class PeSection(LittleEndianStructure):
_fields_ = (
("Name", c_char * 8),
("VirtualSize", c_uint32),
("VirtualAddress", c_uint32),
("SizeOfRawData", c_uint32),
("PointerToRawData", c_uint32),
("PointerToRelocations", c_uint32),
("PointerToLinenumbers", c_uint32),
("NumberOfRelocations", c_uint16),
("NumberOfLinenumbers", c_uint16),
("Characteristics", c_uint32),
)
def __init__(self):
super().__init__()
self.data = bytearray()
N_DATA_DIRECTORY_ENTRIES = 16
assert sizeof(PeSection) == 40
assert sizeof(PeCoffHeader) == 20
assert sizeof(PeOptionalHeader32) == 224
assert sizeof(PeOptionalHeader32Plus) == 240
# EFI mandates 4KiB memory pages.
SECTION_ALIGNMENT = 4096
FILE_ALIGNMENT = 512
# Nobody cares about DOS headers, so put the PE header right after.
PE_OFFSET = 64
def align_to(x: int, align: int) -> int:
return (x + align - 1) & ~(align - 1)
def use_section(elf_s: ELFSection) -> bool:
# These sections are either needed during conversion to PE or are otherwise not needed
# in the final PE image.
IGNORE_SECTIONS = [
".ARM.exidx",
".dynamic",
".dynstr",
".dynsym",
".eh_frame_hdr",
".eh_frame",
".gnu.hash",
".hash",
".note.gnu.build-id",
".rel.dyn",
".rela.dyn",
]
# Known sections we care about and want to be in the final PE.
COPY_SECTIONS = [
".data",
".osrel",
".rodata",
".sbat",
".sdmagic",
".text",
]
# By only dealing with allocating sections we effectively filter out debug sections.
if not elf_s["sh_flags"] & SH_FLAGS.SHF_ALLOC:
return False
if elf_s.name in IGNORE_SECTIONS:
return False
# For paranoia we only handle sections we know of. Any new sections that come up should
# be added to IGNORE_SECTIONS/COPY_SECTIONS and/or the linker script.
if elf_s.name not in COPY_SECTIONS:
raise RuntimeError(f"Unknown section {elf_s.name}, refusing.")
if elf_s["sh_addr"] % SECTION_ALIGNMENT != 0:
raise RuntimeError(f"Section {elf_s.name} is not aligned.")
if len(elf_s.name) > 8:
raise RuntimeError(f"ELF section name {elf_s.name} too long.")
return True
def convert_elf_section(elf_s: ELFSection) -> PeSection:
pe_s = PeSection()
pe_s.Name = elf_s.name.encode()
pe_s.VirtualSize = elf_s.data_size
pe_s.VirtualAddress = elf_s["sh_addr"]
pe_s.SizeOfRawData = align_to(elf_s.data_size, FILE_ALIGNMENT)
pe_s.data = bytearray(elf_s.data())
if elf_s["sh_flags"] & SH_FLAGS.SHF_EXECINSTR:
pe_s.Characteristics = 0x60000020 # CNT_CODE|MEM_READ|MEM_EXECUTE
elif elf_s["sh_flags"] & SH_FLAGS.SHF_WRITE:
pe_s.Characteristics = 0xC0000040 # CNT_INITIALIZED_DATA|MEM_READ|MEM_WRITE
else:
pe_s.Characteristics = 0x40000040 # CNT_INITIALIZED_DATA|MEM_READ
return pe_s
def copy_sections(elf: ELFFile, opt: PeOptionalHeader) -> list[PeSection]:
sections = []
for elf_s in elf.iter_sections():
if not use_section(elf_s):
continue
pe_s = convert_elf_section(elf_s)
if pe_s.Name == b".text":
opt.BaseOfCode = pe_s.VirtualAddress
opt.SizeOfCode += pe_s.VirtualSize
else:
opt.SizeOfInitializedData += pe_s.VirtualSize
if pe_s.Name == b".data" and isinstance(opt, PeOptionalHeader32):
opt.BaseOfData = pe_s.VirtualAddress
sections.append(pe_s)
return sections
def apply_elf_relative_relocation(
reloc: ElfRelocation, image_base: int, sections: list[PeSection], addend_size: int
):
# fmt: off
[target] = [
pe_s for pe_s in sections
if pe_s.VirtualAddress <= reloc["r_offset"] < pe_s.VirtualAddress + len(pe_s.data)
]
# fmt: on
addend_offset = reloc["r_offset"] - target.VirtualAddress
if reloc.is_RELA():
addend = reloc["r_addend"]
else:
addend = target.data[addend_offset : addend_offset + addend_size]
addend = int.from_bytes(addend, byteorder="little")
# This currently assumes that the ELF file has an image base of 0.
value = (image_base + addend).to_bytes(addend_size, byteorder="little")
target.data[addend_offset : addend_offset + addend_size] = value
def convert_elf_reloc_table(
elf: ELFFile,
elf_reloc_table: ElfRelocationTable,
image_base: int,
sections: list[PeSection],
pe_reloc_blocks: dict[int, PeRelocationBlock],
):
NONE_RELOC = {
"EM_386": ENUM_RELOC_TYPE_i386["R_386_NONE"],
"EM_AARCH64": ENUM_RELOC_TYPE_AARCH64["R_AARCH64_NONE"],
"EM_ARM": ENUM_RELOC_TYPE_ARM["R_ARM_NONE"],
"EM_LOONGARCH": 0,
"EM_RISCV": 0,
"EM_X86_64": ENUM_RELOC_TYPE_x64["R_X86_64_NONE"],
}[elf["e_machine"]]
RELATIVE_RELOC = {
"EM_386": ENUM_RELOC_TYPE_i386["R_386_RELATIVE"],
"EM_AARCH64": ENUM_RELOC_TYPE_AARCH64["R_AARCH64_RELATIVE"],
"EM_ARM": ENUM_RELOC_TYPE_ARM["R_ARM_RELATIVE"],
"EM_LOONGARCH": 3,
"EM_RISCV": 3,
"EM_X86_64": ENUM_RELOC_TYPE_x64["R_X86_64_RELATIVE"],
}[elf["e_machine"]]
for reloc in elf_reloc_table.iter_relocations():
if reloc["r_info_type"] == NONE_RELOC:
continue
if reloc["r_info_type"] == RELATIVE_RELOC:
apply_elf_relative_relocation(
reloc, image_base, sections, elf.elfclass // 8
)
# Now that the ELF relocation has been applied, we can create a PE relocation.
block_rva = reloc["r_offset"] & ~0xFFF
if block_rva not in pe_reloc_blocks:
pe_reloc_blocks[block_rva] = PeRelocationBlock(block_rva)
entry = PeRelocationEntry()
entry.Offset = reloc["r_offset"] & 0xFFF
# REL_BASED_HIGHLOW or REL_BASED_DIR64
entry.Type = 3 if elf.elfclass == 32 else 10
pe_reloc_blocks[block_rva].entries.append(entry)
continue
raise RuntimeError(f"Unsupported relocation {reloc}")
def convert_elf_relocations(
elf: ELFFile, opt: PeOptionalHeader, sections: list[PeSection]
) -> PeSection:
dynamic = elf.get_section_by_name(".dynamic")
if dynamic is None:
raise RuntimeError("ELF .dynamic section is missing.")
[flags_tag] = dynamic.iter_tags("DT_FLAGS_1")
if not flags_tag["d_val"] & ENUM_DT_FLAGS_1["DF_1_PIE"]:
raise RuntimeError("ELF file is not a PIE.")
pe_reloc_blocks: dict[int, PeRelocationBlock] = {}
for reloc_type, reloc_table in dynamic.get_relocation_tables().items():
if reloc_type not in ["REL", "RELA"]:
raise RuntimeError("Unsupported relocation type {elf_reloc_type}.")
convert_elf_reloc_table(
elf, reloc_table, opt.ImageBase, sections, pe_reloc_blocks
)
data = bytearray()
for rva in sorted(pe_reloc_blocks):
block = pe_reloc_blocks[rva]
n_relocs = len(block.entries)
# Each block must start on a 32-bit boundary. Because each entry is 16 bits
# the len has to be even. We pad by adding a none relocation.
if n_relocs % 2 != 0:
n_relocs += 1
block.entries.append(PeRelocationEntry())
block.BlockSize = (
sizeof(PeRelocationBlock) + sizeof(PeRelocationEntry) * n_relocs
)
data += block
for entry in sorted(block.entries, key=lambda e: e.Offset):
data += entry
pe_reloc_s = PeSection()
pe_reloc_s.Name = b".reloc"
pe_reloc_s.data = data
pe_reloc_s.VirtualSize = len(data)
pe_reloc_s.SizeOfRawData = align_to(len(data), FILE_ALIGNMENT)
pe_reloc_s.VirtualAddress = align_to(
sections[-1].VirtualAddress + sections[-1].VirtualSize, SECTION_ALIGNMENT
)
# CNT_INITIALIZED_DATA|MEM_READ|MEM_DISCARDABLE
pe_reloc_s.Characteristics = 0x42000040
sections.append(pe_reloc_s)
opt.SizeOfInitializedData += pe_reloc_s.VirtualSize
return pe_reloc_s
def write_pe(
file, coff: PeCoffHeader, opt: PeOptionalHeader, sections: list[PeSection]
):
file.write(b"MZ")
file.seek(0x3C, io.SEEK_SET)
file.write(PE_OFFSET.to_bytes(2, byteorder="little"))
file.seek(PE_OFFSET, io.SEEK_SET)
file.write(b"PE\0\0")
file.write(coff)
file.write(opt)
offset = opt.SizeOfHeaders
for pe_s in sorted(sections, key=lambda s: s.VirtualAddress):
if pe_s.VirtualAddress < opt.SizeOfHeaders:
# Linker script should make sure this does not happen.
raise RuntimeError(f"Section {pe_s.Name} overlapping PE headers.")
pe_s.PointerToRawData = offset
file.write(pe_s)
offset = align_to(offset + len(pe_s.data), FILE_ALIGNMENT)
for pe_s in sections:
file.seek(pe_s.PointerToRawData, io.SEEK_SET)
file.write(pe_s.data)
file.truncate(offset)
def elf2efi(args: argparse.Namespace):
elf = ELFFile(args.ELF)
if not elf.little_endian:
raise RuntimeError("ELF file is not little-endian.")
if elf["e_type"] not in ["ET_DYN", "ET_EXEC"]:
raise RuntimeError("Unsupported ELF type.")
pe_arch = {
"EM_386": 0x014C,
"EM_AARCH64": 0xAA64,
"EM_ARM": 0x01C2,
"EM_LOONGARCH": 0x6232 if elf.elfclass == 32 else 0x6264,
"EM_RISCV": 0x5032 if elf.elfclass == 32 else 0x5064,
"EM_X86_64": 0x8664,
}.get(elf["e_machine"])
if pe_arch is None:
raise RuntimeError(f"Unuspported ELF arch {elf['e_machine']}")
coff = PeCoffHeader()
opt = PeOptionalHeader32() if elf.elfclass == 32 else PeOptionalHeader32Plus()
# We relocate to a unique image base to reduce the chances for runtime relocation to occur.
base_name = pathlib.Path(args.PE.name).name.encode()
opt.ImageBase = int(hashlib.sha1(base_name).hexdigest()[0:8], 16)
if elf.elfclass == 32:
opt.ImageBase = (0x400000 + opt.ImageBase) & 0xFFFF0000
else:
opt.ImageBase = (0x100000000 + opt.ImageBase) & 0x1FFFF0000
sections = copy_sections(elf, opt)
pe_reloc_s = convert_elf_relocations(elf, opt, sections)
coff.Machine = pe_arch
coff.NumberOfSections = len(sections)
coff.TimeDateStamp = int(os.environ.get("SOURCE_DATE_EPOCH", time.time()))
coff.SizeOfOptionalHeader = sizeof(opt)
# EXECUTABLE_IMAGE|LINE_NUMS_STRIPPED|LOCAL_SYMS_STRIPPED|DEBUG_STRIPPED
# and (32BIT_MACHINE or LARGE_ADDRESS_AWARE)
coff.Characteristics = 0x30E if elf.elfclass == 32 else 0x22E
opt.AddressOfEntryPoint = elf["e_entry"]
opt.SectionAlignment = SECTION_ALIGNMENT
opt.FileAlignment = FILE_ALIGNMENT
opt.MajorImageVersion = args.version_major
opt.MinorImageVersion = args.version_minor
opt.MajorSubsystemVersion = args.efi_major
opt.MinorSubsystemVersion = args.efi_minor
opt.Subsystem = args.subsystem
opt.Magic = 0x10B if elf.elfclass == 32 else 0x20B
opt.SizeOfImage = align_to(
sections[-1].VirtualAddress + sections[-1].VirtualSize, SECTION_ALIGNMENT
)
opt.SizeOfHeaders = align_to(
PE_OFFSET
+ coff.SizeOfOptionalHeader
+ sizeof(PeSection) * coff.NumberOfSections,
FILE_ALIGNMENT,
)
# DYNAMIC_BASE|NX_COMPAT|HIGH_ENTROPY_VA or DYNAMIC_BASE|NX_COMPAT
opt.DllCharacteristics = 0x160 if elf.elfclass == 64 else 0x140
# These values are taken from a natively built PE binary (although, unused by EDK2/EFI).
opt.SizeOfStackReserve = 0x100000
opt.SizeOfStackCommit = 0x001000
opt.SizeOfHeapReserve = 0x100000
opt.SizeOfHeapCommit = 0x001000
opt.NumberOfRvaAndSizes = N_DATA_DIRECTORY_ENTRIES
opt.BaseRelocationTable = PeDataDirectory(
pe_reloc_s.VirtualAddress, pe_reloc_s.VirtualSize
)
write_pe(args.PE, coff, opt, sections)
def main():
parser = argparse.ArgumentParser(description="Convert ELF binaries to PE/EFI")
parser.add_argument(
"--version-major",
type=int,
default=0,
help="Major image version of EFI image",
)
parser.add_argument(
"--version-minor",
type=int,
default=0,
help="Minor image version of EFI image",
)
parser.add_argument(
"--efi-major",
type=int,
default=0,
help="Minimum major EFI subsystem version",
)
parser.add_argument(
"--efi-minor",
type=int,
default=0,
help="Minimum minor EFI subsystem version",
)
parser.add_argument(
"--subsystem",
type=int,
default=10,
help="PE subsystem",
)
parser.add_argument(
"ELF",
type=argparse.FileType("rb"),
help="Input ELF file",
)
parser.add_argument(
"PE",
type=argparse.FileType("wb"),
help="Output PE/EFI file",
)
elf2efi(parser.parse_args())
if __name__ == "__main__":
main()

View file

@ -35,18 +35,12 @@ else
apt-get update
apt-get install -y gperf m4 gettext python3-pip \
libcap-dev libmount-dev \
pkg-config wget python3-jinja2 zipmerge
pkg-config wget python3-jinja2 zipmerge zstd
if [[ "$ARCHITECTURE" == i386 ]]; then
apt-get install -y pkg-config:i386 libcap-dev:i386 libmount-dev:i386
fi
# gnu-efi is installed here to enable -Dgnu-efi behind which fuzz-bcd
# is hidden. It isn't linked against efi. It doesn't
# even include "efi.h" because "bcd.c" can work in "unit test" mode
# where it isn't necessary.
apt-get install -y gnu-efi zstd
pip3 install -r .github/workflows/requirements.txt --require-hashes
# https://github.com/google/oss-fuzz/issues/6868

View file

@ -105,9 +105,9 @@ units = [
['systemd-ask-password-wall.path', '',
'multi-user.target.wants/'],
['systemd-ask-password-wall.service', ''],
['systemd-boot-random-seed.service', 'HAVE_GNU_EFI',
['systemd-boot-random-seed.service', 'ENABLE_BOOTLOADER',
'sysinit.target.wants/'],
['systemd-boot-update.service', 'HAVE_GNU_EFI'],
['systemd-boot-update.service', 'ENABLE_BOOTLOADER'],
['systemd-coredump.socket', 'ENABLE_COREDUMP',
'sockets.target.wants/'],
['systemd-exit.service', ''],
@ -187,7 +187,7 @@ in_units = [
['systemd-backlight@.service', 'ENABLE_BACKLIGHT'],
['systemd-binfmt.service', 'ENABLE_BINFMT',
'sysinit.target.wants/'],
['systemd-bless-boot.service', 'HAVE_GNU_EFI HAVE_BLKID'],
['systemd-bless-boot.service', 'ENABLE_BOOTLOADER HAVE_BLKID'],
['systemd-boot-check-no-failures.service', ''],
['systemd-coredump@.service', 'ENABLE_COREDUMP'],
['systemd-pstore.service', 'ENABLE_PSTORE'],
@ -259,16 +259,16 @@ in_units = [
'sysinit.target.wants/ initrd-root-fs.target.wants/'],
['user-runtime-dir@.service', ''],
['user@.service', ''],
['systemd-pcrphase-initrd.service', 'HAVE_GNU_EFI HAVE_OPENSSL HAVE_TPM2 ENABLE_INITRD',
['systemd-pcrphase-initrd.service', 'ENABLE_BOOTLOADER HAVE_OPENSSL HAVE_TPM2 ENABLE_INITRD',
'initrd.target.wants/'],
['systemd-pcrphase-sysinit.service', 'HAVE_GNU_EFI HAVE_OPENSSL HAVE_TPM2',
['systemd-pcrphase-sysinit.service', 'ENABLE_BOOTLOADER HAVE_OPENSSL HAVE_TPM2',
'sysinit.target.wants/'],
['systemd-pcrphase.service', 'HAVE_GNU_EFI HAVE_OPENSSL HAVE_TPM2',
['systemd-pcrphase.service', 'ENABLE_BOOTLOADER HAVE_OPENSSL HAVE_TPM2',
'sysinit.target.wants/'],
['systemd-pcrmachine.service', 'HAVE_GNU_EFI HAVE_OPENSSL HAVE_TPM2',
['systemd-pcrmachine.service', 'ENABLE_BOOTLOADER HAVE_OPENSSL HAVE_TPM2',
'sysinit.target.wants/'],
['systemd-pcrfs-root.service', 'HAVE_GNU_EFI HAVE_OPENSSL HAVE_TPM2'],
['systemd-pcrfs@.service', 'HAVE_GNU_EFI HAVE_OPENSSL HAVE_TPM2'],
['systemd-pcrfs-root.service', 'ENABLE_BOOTLOADER HAVE_OPENSSL HAVE_TPM2'],
['systemd-pcrfs@.service', 'ENABLE_BOOTLOADER HAVE_OPENSSL HAVE_TPM2'],
['systemd-growfs-root.service', ''],
['systemd-growfs@.service', ''],
]