diff --git a/.github/workflows/build_test.sh b/.github/workflows/build_test.sh index 745d2e5cbd0..a2031e65fc6 100755 --- a/.github/workflows/build_test.sh +++ b/.github/workflows/build_test.sh @@ -52,6 +52,7 @@ PACKAGES=( python3-evdev python3-jinja2 python3-lxml + python3-pefile python3-pip python3-pyparsing python3-setuptools diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh index 9a9fbb36ab5..70ba090eb8e 100755 --- a/.github/workflows/unit_tests.sh +++ b/.github/workflows/unit_tests.sh @@ -21,6 +21,7 @@ ADDITIONAL_DEPS=( libzstd-dev perl python3-libevdev + python3-pefile python3-pyparsing rpm zstd diff --git a/README b/README index 92e3ca0f486..aff88de48e1 100644 --- a/README +++ b/README @@ -202,6 +202,7 @@ REQUIREMENTS: docbook-xsl (optional, required for documentation) xsltproc (optional, required for documentation) python-jinja2 + python-pefile python-lxml (optional, required to build the indices) python >= 3.5 meson >= 0.53.2 diff --git a/meson.build b/meson.build index 274e43ba9e7..131016fcbfb 100644 --- a/meson.build +++ b/meson.build @@ -1913,6 +1913,7 @@ catalogs = [] ############################################################ +check_efi_alignment_py = find_program('tools/check-efi-alignment.py') # Include these now as they provide gnu-efi detection. subdir('src/fundamental') subdir('src/boot/efi') diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index c4eb471451b..8a9adbdf8ab 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -494,4 +494,9 @@ foreach tuple : [['systemd-boot@0@.@1@', systemd_boot_objects, false, 'systemd-b install_dir : bootlibdir) alias_target(tuple[3], efi) + + test('check-alignment-@0@'.format(tuple[0].format(efi_arch[0], 'efi')), + check_efi_alignment_py, + args : efi.full_path(), + suite : 'efi') endforeach diff --git a/tools/check-efi-alignment.py b/tools/check-efi-alignment.py new file mode 100755 index 00000000000..26d5f5e40d8 --- /dev/null +++ b/tools/check-efi-alignment.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: LGPL-2.1-or-later +# vi: set tw=110 sw=4 ts=4 et: + +import sys + +try: + import pefile +except ImportError as e: + print(str(e), file=sys.stderr) + sys.exit(77) + + +def main(): + pe = pefile.PE(sys.argv[1], fast_load=True) + + for section in pe.sections: + name = section.Name.rstrip(b"\x00").decode() + file_addr = section.PointerToRawData + virt_addr = section.VirtualAddress + print(f"{name:10s} file=0x{file_addr:08x} virt=0x{virt_addr:08x}") + + if file_addr % 512 != 0: + print(f"File address of {name} section is not aligned to 512 bytes", file=sys.stderr) + return 1 + + if virt_addr % 512 != 0: + print(f"Virt address of {name} section is not aligned to 512 bytes", file=sys.stderr) + return 1 + +if __name__ == '__main__': + if len(sys.argv) != 2: + print(f"Usage: {sys.argv[0]} pe-image") + sys.exit(1) + + sys.exit(main())