diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/boot/efi/boot.c | 1 | ||||
-rw-r--r-- | src/boot/efi/efi-string.h | 2 | ||||
-rw-r--r-- | src/boot/efi/meson.build | 176 | ||||
-rw-r--r-- | src/boot/efi/stub.c | 1 | ||||
-rw-r--r-- | src/boot/efi/util.h | 24 | ||||
-rw-r--r-- | src/fundamental/sbat.h | 2 |
6 files changed, 192 insertions, 14 deletions
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index ff249c8a2e..02c3568062 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -21,6 +21,7 @@ #include "shim.h" #include "ticks.h" #include "util.h" +#include "version.h" #include "vmm.h" /* Magic string for recognizing our own binaries */ 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 6677dc65d8..297eb0f5ee 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -57,7 +57,7 @@ elif get_option('sbat-distro') != '' endif endif -summary({'UEFI architecture' : efi_arch}, +summary({'UEFI architectures' : efi_arch + (efi_arch_alt == '' ? '' : ', ' + efi_arch_alt)}, section : 'UEFI') if efi_conf.get('SBAT_DISTRO', '') != '' @@ -76,6 +76,97 @@ configure_file( ############################################################ +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', +) + +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 + +############################################################ + libefi_sources = files( 'console.c', 'device-path-util.c', @@ -155,3 +246,86 @@ if host_machine.cpu_family() in ['aarch64', 'arm', 'x86_64', 'x86'] }, ] 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 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_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/stub.c b/src/boot/efi/stub.c index 5e813a6eb6..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 */ 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__) diff --git a/src/fundamental/sbat.h b/src/fundamental/sbat.h index b3c09dcb4c..a18da48038 100644 --- a/src/fundamental/sbat.h +++ b/src/fundamental/sbat.h @@ -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" \ |