From c0e4459e09b032161807755ed758685cb2827289 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Fri, 28 Jan 2022 11:33:23 +0100 Subject: [PATCH 1/4] meson: Add efi-cflags option --- meson_options.txt | 2 ++ src/boot/efi/meson.build | 2 ++ 2 files changed, 4 insertions(+) diff --git a/meson_options.txt b/meson_options.txt index 430b03d2b2..a315ca47c5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -422,6 +422,8 @@ option('dbus', type : 'combo', choices : ['auto', 'true', 'false'], option('gnu-efi', type : 'combo', choices : ['auto', 'true', 'false'], description : 'gnu-efi support for sd-boot') +option('efi-cflags', type : 'array', + description : 'additional flags for EFI compiler') # Note that LLD does not support PE/COFF relocations # https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html option('efi-ld', type : 'combo', choices : ['auto', 'bfd', 'gold'], diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index ffee98bbb8..b2b090256c 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -229,6 +229,8 @@ foreach arg : get_option('c_args') endif endforeach +efi_cflags += get_option('efi-cflags') + efi_ldflags = [ '-fuse-ld=' + efi_ld, '-L', efi_libdir, From 7faded269dec9347543b43654cdc99aabc461da7 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Wed, 2 Feb 2022 11:24:41 +0100 Subject: [PATCH 2/4] meson: Add support for building efi binaries on multilib This allows building 32bit versions of efi binaries on x86_64 machines and vice-versa by passing "-Defi-cflags=-m32" to meson, provided the 32bit gnu-efi and gcc-multilib are available. It is expected that distros that want to provide both ia32 and x64 versions to use a second build dir to build the non-native version by adding -m32 to efi-cflags and then running the sd-boot/sd-stub ninja target directly. --- src/boot/efi/meson.build | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index b2b090256c..a17857e63e 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -10,6 +10,12 @@ if not get_option('efi') or get_option('gnu-efi') == 'false' 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), gnu_efi_inc_arch] 'x86': ['ia32', 'ia32'], @@ -17,10 +23,13 @@ efi_arch = { 'arm': ['arm', 'arm'], 'aarch64': ['aa64', 'aarch64'], 'riscv64': ['riscv64', 'riscv64'], -}.get(host_machine.cpu_family(), []) +}.get(efi_arch, []) efi_incdir = get_option('efi-includedir') -if efi_arch.length() > 0 and not cc.has_header('@0@/@1@/efibind.h'.format(efi_incdir, efi_arch[1])) +if efi_arch.length() > 0 and not cc.has_header( + '@0@/@1@/efibind.h'.format(efi_incdir, efi_arch[1]), + args: get_option('efi-cflags')) + efi_arch = [] endif @@ -33,7 +42,7 @@ if efi_arch.length() == 0 endif if not cc.has_header_symbol('efi.h', 'EFI_IMAGE_MACHINE_X64', - args: ['-nostdlib', '-ffreestanding', '-fshort-wchar'], + args: ['-nostdlib', '-ffreestanding', '-fshort-wchar'] + get_option('efi-cflags'), include_directories: include_directories(efi_incdir, efi_incdir / efi_arch[1])) if get_option('gnu-efi') == 'true' @@ -54,14 +63,19 @@ if efi_ld == 'auto' 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], - run_command( - 'realpath', '-e', - '/usr/lib' / run_command(cc.cmd_array(), '-print-multi-os-directory', check: false).stdout().strip(), - check: false - ).stdout().strip()] + efi_multilib] if dir != '' and fs.is_dir(dir) efi_libdir = dir break From 5ec92856113867771a2017c4da4909815326624f Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Thu, 24 Mar 2022 10:35:30 +0100 Subject: [PATCH 3/4] boot: Restrict block IO buf size --- src/boot/efi/boot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index e7e5a6a367..96e56a7839 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -2042,10 +2042,10 @@ static EFI_STATUS boot_windows_bitlocker(void) { for (UINTN i = 0; i < n_handles; i++) { EFI_BLOCK_IO *block_io; err = BS->HandleProtocol(handles[i], &BlockIoProtocol, (void **) &block_io); - if (EFI_ERROR(err) || block_io->Media->BlockSize < 512) + if (EFI_ERROR(err) || block_io->Media->BlockSize < 512 || block_io->Media->BlockSize > 4096) continue; - CHAR8 buf[block_io->Media->BlockSize]; + CHAR8 buf[4096]; err = block_io->ReadBlocks(block_io, block_io->Media->MediaId, 0, sizeof(buf), buf); if (EFI_ERROR(err)) continue; From 7fc60c071fbaeea55518ffbdd3a915c56cdebfb1 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Wed, 23 Mar 2022 14:40:06 +0100 Subject: [PATCH 4/4] ci: Add ia32 EFI multilib test This makes sure that building ia32 EFI binaries on x86_64 works. We force gnu-efi support to ensure it's not skipped by accident and provide the lib32 dir manually, because clang does not support '--print-multi-os-directory', which is used to auto-detect it. --- .github/workflows/build_test.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_test.sh b/.github/workflows/build_test.sh index 7a27a5f9f1..0c77be2a13 100755 --- a/.github/workflows/build_test.sh +++ b/.github/workflows/build_test.sh @@ -9,7 +9,7 @@ success() { echo >&2 -e "\033[32;1m$1\033[0m"; } ARGS=( "--optimization=0" - "--optimization=s" + "--optimization=s -Dgnu-efi=true -Defi-cflags=-m32 -Defi-libdir=/usr/lib32" "--optimization=3 -Db_lto=true -Ddns-over-tls=false" "--optimization=3 -Db_lto=false" "--optimization=3 -Ddns-over-tls=openssl" @@ -27,6 +27,7 @@ PACKAGES=( kbd libblkid-dev libbpf-dev + libc6-dev-i386 libcap-dev libcurl4-gnutls-dev libfdisk-dev @@ -93,7 +94,7 @@ elif [[ "$COMPILER" == gcc ]]; then # Latest gcc stack deb packages provided by # https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test add-apt-repository -y ppa:ubuntu-toolchain-r/test - PACKAGES+=("gcc-$COMPILER_VERSION") + PACKAGES+=("gcc-$COMPILER_VERSION" "gcc-$COMPILER_VERSION-multilib") else fatal "Unknown compiler: $COMPILER" fi