summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/boot/efi/boot.c1
-rw-r--r--src/boot/efi/efi-string.h2
-rw-r--r--src/boot/efi/meson.build176
-rw-r--r--src/boot/efi/stub.c1
-rw-r--r--src/boot/efi/util.h24
-rw-r--r--src/fundamental/sbat.h2
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" \