summaryrefslogtreecommitdiffstats
path: root/src/boot/efi/meson.build
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:49:52 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:49:52 +0000
commit55944e5e40b1be2afc4855d8d2baf4b73d1876b5 (patch)
tree33f869f55a1b149e9b7c2b7e201867ca5dd52992 /src/boot/efi/meson.build
parentInitial commit. (diff)
downloadsystemd-55944e5e40b1be2afc4855d8d2baf4b73d1876b5.tar.xz
systemd-55944e5e40b1be2afc4855d8d2baf4b73d1876b5.zip
Adding upstream version 255.4.upstream/255.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boot/efi/meson.build')
-rw-r--r--src/boot/efi/meson.build409
1 files changed, 409 insertions, 0 deletions
diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build
new file mode 100644
index 0000000..c95132e
--- /dev/null
+++ b/src/boot/efi/meson.build
@@ -0,0 +1,409 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+efi_config_h_dir = meson.current_build_dir()
+efi_addon = ''
+
+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_test_template = test_template + efitest_base
+efi_fuzz_template = fuzz_template + efitest_base
+
+executables += [
+ efi_test_template + {
+ 'sources' : files('test-bcd.c'),
+ 'dependencies' : libzstd,
+ 'conditions' : ['ENABLE_BOOTLOADER', 'HAVE_ZSTD'],
+ },
+ efi_test_template + {
+ 'sources' : files('test-efi-string.c'),
+ 'conditions' : ['ENABLE_BOOTLOADER'],
+ },
+ efi_fuzz_template + {
+ 'sources' : files('fuzz-bcd.c'),
+ },
+ efi_fuzz_template + {
+ 'sources' : files('fuzz-efi-string.c'),
+ },
+ efi_fuzz_template + {
+ 'sources' : files('fuzz-efi-osrel.c'),
+ },
+ efi_fuzz_template + {
+ 'sources' : files('fuzz-efi-printf.c'),
+ },
+]
+
+if conf.get('ENABLE_BOOTLOADER') != 1
+ subdir_done()
+endif
+
+efi_conf = configuration_data()
+efi_conf.set10('ENABLE_TPM', get_option('tpm'))
+
+foreach ctype : ['color-normal', 'color-entry', 'color-highlight', 'color-edit']
+ c = get_option('efi-' + ctype).split(',')
+ efi_conf.set(ctype.underscorify().to_upper(), 'EFI_TEXT_ATTR(@0@, @1@)'.format(
+ 'EFI_' + c[0].strip().underscorify().to_upper(),
+ 'EFI_' + c[1].strip().underscorify().to_upper()))
+endforeach
+
+if meson.is_cross_build() and get_option('sbat-distro') == 'auto'
+ warning('Auto detection of SBAT information not supported when cross-building, disabling SBAT.')
+elif get_option('sbat-distro') != ''
+ efi_conf.set_quoted('SBAT_PROJECT', meson.project_name())
+ efi_conf.set_quoted('PROJECT_VERSION', meson.project_version())
+ efi_conf.set('PROJECT_URL', conf.get('PROJECT_URL'))
+ if get_option('sbat-distro-generation') < 1
+ error('SBAT Distro Generation must be a positive integer')
+ endif
+ efi_conf.set('SBAT_DISTRO_GENERATION', get_option('sbat-distro-generation'))
+ foreach sbatvar : [['sbat-distro', 'ID'],
+ ['sbat-distro-summary', 'NAME'],
+ ['sbat-distro-url', 'BUG_REPORT_URL']]
+ value = get_option(sbatvar[0])
+ if (value == '' or value == 'auto') and not meson.is_cross_build()
+ cmd = 'if [ -e /etc/os-release ]; then . /etc/os-release; else . /usr/lib/os-release; fi; echo $@0@'.format(sbatvar[1])
+ value = run_command(sh, '-c', cmd, check: true).stdout().strip()
+ endif
+ if value == ''
+ error('Required @0@ option not set and autodetection failed'.format(sbatvar[0]))
+ endif
+ efi_conf.set_quoted(sbatvar[0].underscorify().to_upper(), value)
+ endforeach
+
+ pkgname = get_option('sbat-distro-pkgname')
+ if pkgname == ''
+ pkgname = meson.project_name()
+ endif
+ efi_conf.set_quoted('SBAT_DISTRO_PKGNAME', pkgname)
+
+ pkgver = get_option('sbat-distro-version')
+ if pkgver == ''
+ # This is determined during build, not configuration, so we can't display it yet.
+ efi_conf.set('SBAT_DISTRO_VERSION', 'GIT_VERSION')
+ else
+ efi_conf.set_quoted('SBAT_DISTRO_VERSION', pkgver)
+ endif
+endif
+
+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': efi_conf.get('SBAT_DISTRO_VERSION'),
+ '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_includes = [
+ build_dir_include,
+ 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',
+ '-mstack-protector-guard=global',
+)
+
+# 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 = [
+ '-lgcc',
+ '-nostdlib',
+ '-static-pie',
+ '-Wl,--entry=efi_main',
+ '-Wl,--fatal-warnings',
+
+ # These flags should be passed by -static-pie, but for whatever reason the flag translation
+ # is not enabled on all architectures. Not passing `-static` would just allow the linker to
+ # use dynamic libraries, (which we can't/don't use anyway). But if `-pie` is missing and the
+ # gcc build does not default to `-pie` we get a regular (no-pie) binary that will be
+ # rightfully rejected by elf2efi. Note that meson also passes `-pie` to the linker driver,
+ # but it is overridden by our `-static-pie`. We also need to pass these directly to the
+ # linker as `-static`+`-pie` seem to get translated differently.
+ '-Wl,-static,-pie,--no-dynamic-linker,-z,text',
+
+ # EFI has 4KiB pages.
+ '-z', 'common-page-size=4096',
+ '-z', 'max-page-size=4096',
+
+ '-z', 'noexecstack',
+ '-z', 'relro',
+ '-z', 'separate-code',
+]
+
+efi_c_ld_args += cc.get_supported_link_arguments(
+ # binutils >= 2.38
+ '-Wl,-z,nopack-relative-relocs',
+)
+
+# 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-unwind-tables',
+)
+efi_override_options = [
+ 'b_coverage=false',
+ 'b_pgo=off',
+]
+
+if get_option('b_sanitize') == 'undefined'
+ efi_disabled_c_args += cc.get_supported_arguments('-fno-sanitize-link-runtime')
+else
+ efi_disabled_c_args += cc.get_supported_arguments('-fno-sanitize=all')
+ efi_override_options += 'b_sanitize=none'
+endif
+
+efi_c_args += efi_disabled_c_args
+efi_c_ld_args += efi_disabled_c_args
+
+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
+
+efi_arch_c_args = {
+ 'aarch64' : ['-mgeneral-regs-only'],
+ 'arm' : ['-mgeneral-regs-only'],
+ # Pass -m64/32 explicitly to make building on x32 work.
+ 'x86_64' : ['-m64', '-march=x86-64', '-mno-red-zone', '-mgeneral-regs-only'],
+ 'x86' : ['-m32', '-march=i686', '-mgeneral-regs-only', '-malign-double'],
+}
+efi_arch_c_ld_args = {
+ # libgcc is not compiled with -fshort-wchar, but it does not use it anyways,
+ # so it's fine to link against it.
+ 'arm' : cc.get_supported_link_arguments('-Wl,--no-wchar-size-warning'),
+ 'x86_64' : ['-m64'],
+ 'x86' : ['-m32'],
+}
+
+linker_sanity_code = 'void a(void) {}; void _start(void) { a(); }'
+linker_sanity_args = ['-nostdlib', '-Wl,--fatal-warnings']
+if not cc.links(linker_sanity_code,
+ name : 'linker supports -static-pie',
+ args : [linker_sanity_args, '-static-pie'])
+ error('Linker does not support -static-pie.')
+endif
+
+# https://github.com/llvm/llvm-project/issues/67152
+if not cc.links(linker_sanity_code,
+ name : 'linker supports LTO with -nostdlib',
+ args : [linker_sanity_args, '-flto'])
+ efi_c_args += '-fno-lto'
+ efi_c_ld_args += '-fno-lto'
+endif
+
+# https://github.com/llvm/llvm-project/issues/61101
+if efi_cpu_family_alt == 'x86' and not cc.links(linker_sanity_code,
+ name : 'linker supports LTO with -nostdlib (x86)',
+ args : [linker_sanity_args, '-flto', '-m32'])
+ efi_arch_c_args += { 'x86' : efi_arch_c_args['x86'] + '-fno-lto' }
+ efi_arch_c_ld_args += { 'x86' : efi_arch_c_ld_args['x86'] + '-fno-lto' }
+endif
+
+############################################################
+
+libefi_sources = files(
+ 'console.c',
+ 'device-path-util.c',
+ 'devicetree.c',
+ 'drivers.c',
+ 'efi-string.c',
+ 'graphics.c',
+ 'initrd.c',
+ 'log.c',
+ 'measure.c',
+ 'part-discovery.c',
+ 'pe.c',
+ 'random-seed.c',
+ 'secure-boot.c',
+ 'shim.c',
+ 'ticks.c',
+ 'util.c',
+ 'vmm.c',
+)
+
+systemd_boot_sources = files(
+ 'boot.c',
+)
+
+stub_sources = files(
+ 'cpio.c',
+ 'linux.c',
+ 'splash.c',
+ 'stub.c',
+)
+
+addon_sources = files(
+ 'addon.c',
+)
+
+if get_option('b_sanitize') == 'undefined'
+ libefi_sources += files('ubsan.c')
+endif
+
+if host_machine.cpu_family() in ['x86', 'x86_64']
+ stub_sources += files('linux_x86.c')
+endif
+
+# 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 = [
+ {
+ 'arch' : efi_arch,
+ 'c_args' : [
+ efi_c_args,
+ '-DEFI_MACHINE_TYPE_NAME="' + efi_arch + '"',
+ efi_arch_c_args.get(host_machine.cpu_family(), []),
+ ],
+ 'link_args' : [
+ efi_c_ld_args,
+ efi_arch_c_ld_args.get(host_machine.cpu_family(), []),
+ ],
+ },
+]
+if efi_arch_alt != ''
+ efi_archspecs += {
+ 'arch' : efi_arch_alt,
+ 'c_args' : [
+ efi_c_args,
+ '-DEFI_MACHINE_TYPE_NAME="' + efi_arch_alt + '"',
+ efi_arch_c_args.get(efi_cpu_family_alt, []),
+ ],
+ 'link_args' : [
+ efi_c_ld_args,
+ efi_arch_c_ld_args.get(efi_cpu_family_alt, []),
+ ],
+ }
+endif
+
+foreach archspec : efi_archspecs
+ libefi = static_library(
+ 'efi' + archspec['arch'],
+ fundamental_sources,
+ libefi_sources,
+ version_h,
+ include_directories : efi_includes,
+ c_args : archspec['c_args'],
+ gnu_symbol_visibility : 'hidden',
+ override_options : efi_override_options,
+ pic : true)
+
+ kwargs = {
+ 'include_directories' : efi_includes,
+ 'c_args' : archspec['c_args'],
+ 'link_args' : archspec['link_args'],
+ 'gnu_symbol_visibility' : 'hidden',
+ 'override_options' : efi_override_options,
+ 'pie' : true,
+ }
+
+ efi_elf_binaries += executable(
+ 'systemd-boot' + archspec['arch'],
+ sources : [systemd_boot_sources, version_h],
+ link_with : libefi,
+ name_suffix : 'elf',
+ kwargs : kwargs)
+
+ efi_elf_binaries += executable(
+ 'linux' + archspec['arch'],
+ sources : [stub_sources, version_h],
+ link_with : libefi,
+ name_suffix : 'elf.stub',
+ kwargs : kwargs)
+
+ efi_elf_binaries += executable(
+ 'addon' + archspec['arch'],
+ sources : [addon_sources, version_h],
+ name_suffix : 'elf.stub',
+ kwargs : kwargs)
+endforeach
+
+foreach efi_elf_binary : efi_elf_binaries
+ name = efi_elf_binary.name()
+ name += name.startswith('systemd-boot') ? '.efi' : '.efi.stub'
+ # For the addon, given it's empty, we need to explicitly reserve space in the header to account for
+ # the sections that ukify will add.
+ minimum_sections = name.endswith('.stub') ? '15' : '0'
+ exe = 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',
+ '--minimum-sections=' + minimum_sections,
+ '--copy-sections=.sbat,.sdmagic,.osrel',
+ '@INPUT@',
+ '@OUTPUT@',
+ ])
+ boot_targets += exe
+ if name.startswith('linux')
+ boot_stubs += exe
+ endif
+
+ # This is supposed to match exactly one time
+ if name == 'addon@0@.efi.stub'.format(efi_arch)
+ efi_addon = exe.full_path()
+ endif
+endforeach
+
+alias_target('systemd-boot', boot_targets)