From dfca5587cf2032f9ad06041b93b0da5cb39b9989 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sun, 26 Feb 2023 14:09:44 +0100 Subject: tree-wide: Drop gnu-efi This drops all mentions of gnu-efi and its manual build machinery. A future commit will bring bootloader builds back. A new bootloader meson option is now used to control whether to build sd-boot and its userspace tooling. --- src/boot/efi/boot.c | 12 -- src/boot/efi/meson.build | 375 ++--------------------------------------------- src/boot/efi/stub.c | 5 - 3 files changed, 11 insertions(+), 381 deletions(-) (limited to 'src/boot') diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index ee507e379a..ff249c8a2e 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -23,13 +23,6 @@ #include "util.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 " ####"; @@ -2735,8 +2728,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/meson.build b/src/boot/efi/meson.build index ea55f1c9fa..6677dc65d8 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -1,129 +1,12 @@ # 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 - -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') +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,151 +57,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 architecture' : efi_arch}, + section : 'UEFI') if efi_conf.get('SBAT_DISTRO', '') != '' summary({ @@ -327,49 +67,16 @@ 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_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,7 +107,7 @@ 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 @@ -414,7 +121,7 @@ tests += [ ] # 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 += [ { @@ -448,63 +155,3 @@ if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64'] }, ] 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 -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@'], - install : true, - install_tag: tuple[3], - install_dir : bootlibdir) - - alias_target(tuple[3], efi) -endforeach diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 25c81ca164..5e813a6eb6 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -423,8 +423,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); -} -- cgit v1.2.1 From 2afeaf1675a6a68636be493a9461e72ce067db19 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Mon, 27 Feb 2023 16:54:48 +0100 Subject: boot: Bring back bootloader builds This adds back sd-boot builds by using meson compile targets directly. We can do this now, because userspace binaries use the special dependency that allows us to easily separate flags, so that we don't pass anything to EFI builds that shouldn't be passed. Additionally, we pass a bunch of flags to hopefully disable/override any distro provided flags that should not be used for EFI binaries. Fixes: #12275 --- src/boot/efi/boot.c | 1 + src/boot/efi/efi-string.h | 2 +- src/boot/efi/meson.build | 176 +++++++++++++++++++++++++++++++++++++++++++++- src/boot/efi/stub.c | 1 + src/boot/efi/util.h | 24 +++---- 5 files changed, 190 insertions(+), 14 deletions(-) (limited to 'src/boot') 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__) -- cgit v1.2.1 From c4ad9b23cafd67e87abbcdcb186db470a5a487e4 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 28 Feb 2023 17:44:05 +0100 Subject: boot: Fix debug experience --- src/boot/efi/meson.build | 7 +++++++ src/boot/efi/util.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src/boot') diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 297eb0f5ee..6b04cfb495 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -92,6 +92,13 @@ efi_c_args += cc.get_supported_arguments( '-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. 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"); -- cgit v1.2.1 From 31ffb6b183bafb4c005ba86bf10f961e07e42e0c Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 28 Feb 2023 18:05:18 +0100 Subject: boot: Add RISCV32 and LoongArch support This is completely untested, but should work in theory, as it's just adding a couple defines according to the specs. --- src/boot/efi/pe.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/boot') 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 -- cgit v1.2.1 From 5d5525245b67c22253df859f2657df18fa13f07f Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Thu, 2 Mar 2023 17:11:52 +0100 Subject: boot: Fix unused function warning --- src/boot/efi/boot.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/boot') diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 02c3568062..6959482ab6 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1960,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; @@ -2040,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__) -- cgit v1.2.1 From 2c7c68e4e404a24aaebc7ee1bae6661c95fe3d54 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sat, 4 Mar 2023 14:10:35 +0100 Subject: meson: Use static library for EFI tests This also moves them so that fuzz builds do not need pyelftools around. --- src/boot/efi/meson.build | 89 ++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 40 deletions(-) (limited to 'src/boot') diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 6b04cfb495..7e497f7866 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -2,6 +2,55 @@ efi_config_h_dir = meson.current_build_dir() +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 @@ -209,49 +258,9 @@ 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 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 boot_targets = [] -- cgit v1.2.1