summaryrefslogtreecommitdiff
path: root/src/boot
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-03-11 17:15:01 +0900
committerGitHub <noreply@github.com>2023-03-11 17:15:01 +0900
commitc9501b03cd43b6d677314bc7ae557d90f282a8c8 (patch)
treeff6113b1ce743802f9ff3f05efb57a6a37996807 /src/boot
parent91e07dd476c75048e9707b0e0b2026877ece739d (diff)
parent2c7c68e4e404a24aaebc7ee1bae6661c95fe3d54 (diff)
downloadsystemd-c9501b03cd43b6d677314bc7ae557d90f282a8c8.tar.gz
Merge pull request #26641 from medhefgo/boot-elf2efi
boot: Drop gnu-efi / Add elf2efi.py
Diffstat (limited to 'src/boot')
-rw-r--r--src/boot/efi/boot.c15
-rw-r--r--src/boot/efi/efi-string.h2
-rw-r--r--src/boot/efi/meson.build601
-rw-r--r--src/boot/efi/pe.c6
-rw-r--r--src/boot/efi/stub.c6
-rw-r--r--src/boot/efi/util.c4
-rw-r--r--src/boot/efi/util.h24
7 files changed, 244 insertions, 414 deletions
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index ee507e379a..6959482ab6 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -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);
-}
diff --git a/src/boot/efi/efi-string.h b/src/boot/efi/efi-string.h
index 4df37a8505..b97e16990a 100644
--- a/src/boot/efi/efi-string.h
+++ b/src/boot/efi/efi-string.h
@@ -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"
diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build
index ea55f1c9fa..7e497f7866 100644
--- a/src/boot/efi/meson.build
+++ b/src/boot/efi/meson.build
@@ -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
- 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
+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,
+ ],
+ }
-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()
+ 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
-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')
+if conf.get('ENABLE_BOOTLOADER') != 1
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,202 +106,124 @@ elif get_option('sbat-distro') != ''
endif
endif
-efi_config_h = configure_file(
+summary({'UEFI architectures' : efi_arch + (efi_arch_alt == '' ? '' : ', ' + efi_arch_alt)},
+ section : 'UEFI')
+
+if efi_conf.get('SBAT_DISTRO', '') != ''
+ summary({
+ 'SBAT distro': efi_conf.get('SBAT_DISTRO'),
+ 'SBAT distro generation': efi_conf.get('SBAT_DISTRO_GENERATION'),
+ '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 : 'UEFI')
+endif
+
+configure_file(
output : 'efi_config.h',
configuration : efi_conf)
-efi_cflags = [
- '-DGNU_EFI_USE_MS_ABI',
+############################################################
+
+efi_includes = [fundamental_include, include_directories('.')]
+
+efi_c_args = [
'-DSD_BOOT=1',
'-ffreestanding',
+ '-fno-strict-aliasing',
'-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], []))
+ '-include', 'efi_config.h',
+]
-# 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.
+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',
+)
-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']
+# 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
-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_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',
-efi_cflags += get_option('efi-cflags')
-
-efi_ldflags = [
- '-fuse-ld=' + efi_ld,
- '-L', efi_libdir,
+ '-lgcc',
'-nostdlib',
- '-T', efi_lds,
- '-Wl,--build-id=sha1',
+ '-static-pie',
+ '-Wl,--entry=efi_main',
'-Wl,--fatal-warnings',
- '-Wl,--no-undefined',
- '-Wl,--warn-common',
- '-Wl,-Bsymbolic',
- '-z', 'nocombreloc',
+
+ # 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',
- efi_crt0,
+ '-z', 'norelro',
+ '-T' + elf2efi_lds,
]
-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
+# 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 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])]
+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 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']
+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
-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')
-
-if efi_conf.get('SBAT_DISTRO', '') != ''
- summary({
- 'SBAT distro': efi_conf.get('SBAT_DISTRO'),
- 'SBAT distro generation': efi_conf.get('SBAT_DISTRO_GENERATION'),
- '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')
+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 += [
+# BCD parser only makes sense on arches that Windows supports.
+if host_machine.cpu_family() in ['aarch64', 'arm', 'x86_64', 'x86']
+ systemd_boot_sources += files('bcd.c')
+endif
+
+boot_targets = []
+efi_elf_binaries = []
+efi_archspecs = [
{
- 'sources' : files(
- 'test-efi-string.c',
- 'efi-string.c',
- )
+ 'arch' : efi_arch,
+ 'c_args' : efi_c_args_primary,
+ 'link_args' : efi_c_ld_args_primary,
},
]
-
-# BCD parser only makes sense on arches that Windows supports.
-if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64']
- 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'
- ),
- },
- ]
+if efi_arch_alt != ''
+ efi_archspecs += {
+ 'arch' : efi_arch_alt,
+ 'c_args' : efi_c_args_alt,
+ 'link_args' : efi_c_ld_args_alt,
+ }
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
+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)
diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c
index 5128eeecb5..9b1b10d4a1 100644
--- a/src/boot/efi/pe.c
+++ b/src/boot/efi/pe.c
@@ -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
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
index 25c81ca164..6339d82ddc 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
@@ -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);
-}
diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c
index 588d60dd06..c8bbe75277 100644
--- a/src/boot/efi/util.c
+++ b/src/boot/efi/util.c
@@ -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");
diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
index a28228c4cc..5e1085c788 100644
--- a/src/boot/efi/util.h
+++ b/src/boot/efi/util.h
@@ -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__)