summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-11-05 14:53:47 +0100
committerGitHub <noreply@github.com>2021-11-05 14:53:47 +0100
commit7f9521d5e12ca9b1bee530dfe2e0218c07f3d7fa (patch)
tree1cf7fae67f439e39a1301da3caa48dff09c55d55 /src
parentbasic/mountpoint-util: detect erofs as a read-only FS (diff)
parentsd-boot: Fix efi_arch checks (diff)
downloadsystemd-7f9521d5e12ca9b1bee530dfe2e0218c07f3d7fa.tar.xz
systemd-7f9521d5e12ca9b1bee530dfe2e0218c07f3d7fa.zip
Merge pull request #21225 from medhefgo/boot-cleanup
Boot cleanup
Diffstat (limited to 'src')
-rw-r--r--src/basic/macro.h7
-rw-r--r--src/boot/efi/boot.c50
-rw-r--r--src/boot/efi/cpio.c2
-rw-r--r--src/boot/efi/drivers.c2
-rw-r--r--src/boot/efi/meson.build64
-rwxr-xr-xsrc/boot/efi/no-undefined-symbols.sh9
-rw-r--r--src/boot/efi/pe.c14
-rw-r--r--src/boot/efi/stub.c19
-rw-r--r--src/boot/efi/util.c11
-rw-r--r--src/fundamental/macro-fundamental.h7
10 files changed, 96 insertions, 89 deletions
diff --git a/src/basic/macro.h b/src/basic/macro.h
index 03a0d061b8..aa04039e80 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -328,13 +328,6 @@ static inline int __coverity_check_and_return__(int condition) {
ans; \
})
-#define UPDATE_FLAG(orig, flag, b) \
- ((b) ? ((orig) | (flag)) : ((orig) & ~(flag)))
-#define SET_FLAG(v, flag, b) \
- (v) = UPDATE_FLAG(v, flag, b)
-#define FLAGS_SET(v, flags) \
- ((~(v) & (flags)) == 0)
-
#define SWAP_TWO(x, y) do { \
typeof(x) _t = (x); \
(x) = (y); \
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index db0c22d405..296efdd489 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -551,7 +551,7 @@ static EFI_STATUS reboot_into_firmware(void) {
UINT64 osind = 0;
EFI_STATUS err;
- if (!(get_os_indications_supported() & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
+ if (!FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
return log_error_status_stall(EFI_UNSUPPORTED, L"Reboot to firmware interface not supported.");
(void) efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndications", &osind);
@@ -924,7 +924,7 @@ static BOOLEAN menu_run(
case KEYPRESS(0, SCAN_F10, 0): /* HP and Lenovo. */
case KEYPRESS(0, SCAN_DELETE, 0): /* Same as F2. */
case KEYPRESS(0, SCAN_ESC, 0): /* HP. */
- if (get_os_indications_supported() & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) {
+ if (FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) {
firmware_setup = TRUE;
/* Let's make sure the user really wants to do this. */
status = PoolPrint(L"Press Enter to reboot into firmware interface.");
@@ -1590,7 +1590,7 @@ static void config_load_entries(
if (f->FileName[0] == '.')
continue;
- if (f->Attribute & EFI_FILE_DIRECTORY)
+ if (FLAGS_SET(f->Attribute, EFI_FILE_DIRECTORY))
continue;
if (!endswith_no_case(f->FileName, L".conf"))
@@ -2026,16 +2026,23 @@ static void config_entry_add_linux(
return;
for (;;) {
+ enum {
+ SECTION_CMDLINE,
+ SECTION_OSREL,
+ _SECTION_MAX,
+ };
+
+ static const CHAR8* const sections[_SECTION_MAX + 1] = {
+ [SECTION_CMDLINE] = (const CHAR8 *) ".cmdline",
+ [SECTION_OSREL] = (const CHAR8 *) ".osrel",
+ NULL,
+ };
+
_cleanup_freepool_ CHAR16 *os_name_pretty = NULL, *os_name = NULL, *os_id = NULL,
*os_version = NULL, *os_version_id = NULL, *os_build_id = NULL, *os_image_version = NULL;
_cleanup_freepool_ CHAR8 *content = NULL;
- const CHAR8 *sections[] = {
- (CHAR8 *)".osrel",
- (CHAR8 *)".cmdline",
- NULL
- };
- UINTN offs[ELEMENTSOF(sections)-1] = {};
- UINTN szs[ELEMENTSOF(sections)-1] = {};
+ UINTN offs[_SECTION_MAX] = {};
+ UINTN szs[_SECTION_MAX] = {};
CHAR8 *line;
UINTN pos = 0;
CHAR8 *key, *value;
@@ -2046,7 +2053,7 @@ static void config_entry_add_linux(
if (f->FileName[0] == '.')
continue;
- if (f->Attribute & EFI_FILE_DIRECTORY)
+ if (FLAGS_SET(f->Attribute, EFI_FILE_DIRECTORY))
continue;
if (!endswith_no_case(f->FileName, L".efi"))
continue;
@@ -2054,11 +2061,11 @@ static void config_entry_add_linux(
continue;
/* look for .osrel and .cmdline sections in the .efi binary */
- err = pe_file_locate_sections(linux_dir, f->FileName, sections, offs, szs);
- if (EFI_ERROR(err))
+ err = pe_file_locate_sections(linux_dir, f->FileName, (const CHAR8**) sections, offs, szs);
+ if (EFI_ERROR(err) || szs[SECTION_OSREL] == 0)
continue;
- err = file_read(linux_dir, f->FileName, offs[0], szs[0], &content, NULL);
+ err = file_read(linux_dir, f->FileName, offs[SECTION_OSREL], szs[SECTION_OSREL], &content, NULL);
if (EFI_ERROR(err))
continue;
@@ -2122,21 +2129,24 @@ static void config_entry_add_linux(
path,
os_image_version ?: (os_version ?: (os_version_id ? : os_build_id)));
+ config_entry_parse_tries(entry, L"\\EFI\\Linux", f->FileName, L".efi");
+
+ if (szs[SECTION_CMDLINE] == 0)
+ continue;
+
FreePool(content);
content = NULL;
/* read the embedded cmdline file */
- err = file_read(linux_dir, f->FileName, offs[1], szs[1], &content, NULL);
+ err = file_read(linux_dir, f->FileName, offs[SECTION_CMDLINE], szs[SECTION_CMDLINE], &content, NULL);
if (!EFI_ERROR(err)) {
/* chomp the newline */
- if (content[szs[1]-1] == '\n')
- content[szs[1]-1] = '\0';
+ if (content[szs[SECTION_CMDLINE] - 1] == '\n')
+ content[szs[SECTION_CMDLINE] - 1] = '\0';
entry->options = stra_to_str(content);
}
-
- config_entry_parse_tries(entry, L"\\EFI\\Linux", f->FileName, L".efi");
}
}
}
@@ -2352,7 +2362,7 @@ static void config_load_all_entries(
config_entry_add_loader_auto(config, loaded_image->DeviceHandle, root_dir, loaded_image_path,
L"auto-efi-default", '\0', L"EFI Default Loader", NULL);
- if (config->auto_firmware && (get_os_indications_supported() & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
+ if (config->auto_firmware && FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
config_entry_add_call(config,
L"auto-reboot-to-firmware-setup",
L"Reboot Into Firmware Interface",
diff --git a/src/boot/efi/cpio.c b/src/boot/efi/cpio.c
index bb7c988031..1818fbedd0 100644
--- a/src/boot/efi/cpio.c
+++ b/src/boot/efi/cpio.c
@@ -375,7 +375,7 @@ EFI_STATUS pack_cpio(
if (dirent->FileName[0] == '.')
continue;
- if (dirent->Attribute & EFI_FILE_DIRECTORY)
+ if (FLAGS_SET(dirent->Attribute, EFI_FILE_DIRECTORY))
continue;
if (match_suffix && !endswith_no_case(dirent->FileName, match_suffix))
continue;
diff --git a/src/boot/efi/drivers.c b/src/boot/efi/drivers.c
index 3ae8f0dde7..4bb4dedaa0 100644
--- a/src/boot/efi/drivers.c
+++ b/src/boot/efi/drivers.c
@@ -103,7 +103,7 @@ EFI_STATUS load_drivers(
if (dirent->FileName[0] == '.')
continue;
- if (dirent->Attribute & EFI_FILE_DIRECTORY)
+ if (FLAGS_SET(dirent->Attribute, EFI_FILE_DIRECTORY))
continue;
if (!endswith_no_case(dirent->FileName, EFI_MACHINE_TYPE_NAME L".efi"))
continue;
diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build
index e6bb7d7c6a..40b0ab0dbd 100644
--- a/src/boot/efi/meson.build
+++ b/src/boot/efi/meson.build
@@ -45,6 +45,12 @@ stub_sources = '''
cpio.c
'''.split()
+if efi_arch in ['x86', 'x86_64']
+ stub_sources += 'linux_x86.c'
+else
+ stub_sources += 'linux.c'
+endif
+
if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false'
efi_cc = get_option('efi-cc')
if efi_cc.length() == 0
@@ -197,11 +203,10 @@ if have_gnu_efi
compile_args = cc.get_supported_arguments(
basic_disabled_warnings +
possible_common_cc_flags + [
- '-ffreestanding',
'-fno-stack-protector',
'-fno-strict-aliasing',
'-fpic',
- '-fshort-wchar',
+ '-fwide-exec-charset=UCS2',
'-Wall',
'-Wextra',
'-Wsign-compare',
@@ -209,6 +214,8 @@ if have_gnu_efi
) + [
'-nostdlib',
'-std=gnu99',
+ '-ffreestanding',
+ '-fshort-wchar',
'-isystem', efi_incdir,
'-isystem', efi_incdir / gnu_efi_path_arch,
'-I', fundamental_path,
@@ -217,46 +224,52 @@ if have_gnu_efi
'-include', efi_config_h,
'-include', version_h,
]
- if ['ia32', 'x86_64'].contains(efi_arch)
- stub_sources += 'linux_x86.c'
- else
- stub_sources += 'linux.c'
- endif
+
if efi_arch == 'x86_64'
compile_args += ['-mno-red-zone',
'-mno-sse',
'-mno-mmx']
- elif efi_arch == 'ia32'
+ elif efi_arch == 'x86'
compile_args += ['-mno-sse',
'-mno-mmx']
elif efi_arch == 'arm'
- if cc.has_argument('-mgeneral-regs-only')
- compile_args += ['-mgeneral-regs-only']
- endif
-
- if cc.has_argument('-mfpu=none')
- compile_args += ['-mfpu=none']
- endif
+ compile_args += cc.get_supported_arguments([
+ '-mgeneral-regs-only',
+ '-mfpu=none'
+ ])
endif
- if get_option('werror') == true
+
+ # 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')
compile_args += ['-Werror']
endif
- if get_option('buildtype') == 'debug'
- compile_args += ['-ggdb', '-O0', '-DEFI_DEBUG']
- elif get_option('buildtype') == 'debugoptimized'
- compile_args += ['-ggdb', '-Og', '-DEFI_DEBUG']
- else
- compile_args += ['-O2']
+ if get_option('debug')
+ compile_args += ['-ggdb', '-DEFI_DEBUG']
+ endif
+ if get_option('optimization') != '0'
+ compile_args += ['-O' + get_option('optimization')]
endif
if get_option('b_ndebug') == 'true' or (
get_option('b_ndebug') == 'if-release' and ['plain', 'release'].contains(get_option('buildtype')))
compile_args += ['-DNDEBUG']
endif
+ foreach arg : get_option('c_args')
+ if arg in ['-Werror', '-g', '-ggdb', '-O1', '-O2', '-O3', '-Og', '-Os', '-DNDEBUG']
+ message('Using "@0@" from c_args for EFI compiler'.format(arg))
+ compile_args += arg
+ endif
+ endforeach
+
efi_ldflags = ['-T', efi_lds,
'-shared',
'-Bsymbolic',
'-nostdlib',
+ '--no-undefined',
+ '--warn-common',
+ '--fatal-warnings',
'-znocombreloc',
'--build-id=sha1',
'-L', efi_libdir,
@@ -291,7 +304,6 @@ if have_gnu_efi
systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(EFI_MACHINE_TYPE_NAME)
stub_elf_name = 'linux@0@.elf.stub'.format(EFI_MACHINE_TYPE_NAME)
stub_efi_name = 'linux@0@.efi.stub'.format(EFI_MACHINE_TYPE_NAME)
- no_undefined_symbols = find_program('no-undefined-symbols.sh')
efi_stubs = []
foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects, false],
@@ -325,12 +337,6 @@ if have_gnu_efi
install_dir : bootlibdir)
efi_stubs += [[so, stub]]
-
- if want_tests != 'false'
- test('no-undefined-symbols-' + tuple[0],
- no_undefined_symbols,
- args : so)
- endif
endforeach
############################################################
diff --git a/src/boot/efi/no-undefined-symbols.sh b/src/boot/efi/no-undefined-symbols.sh
deleted file mode 100755
index 8bdb16accf..0000000000
--- a/src/boot/efi/no-undefined-symbols.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-set -eu
-set -o pipefail
-
-if nm -D -u "${1:?}" | grep ' U '; then
- echo "Undefined symbols detected!"
- exit 1
-fi
diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c
index 6aecfe4526..e87b720dfa 100644
--- a/src/boot/efi/pe.c
+++ b/src/boot/efi/pe.c
@@ -122,7 +122,8 @@ static inline BOOLEAN verify_pe(const struct PeFileHeader *pe) {
return CompareMem(pe->Magic, PE_FILE_MAGIC, STRLEN(PE_FILE_MAGIC)) == 0 &&
pe->FileHeader.Machine == TARGET_MACHINE_TYPE &&
pe->FileHeader.NumberOfSections > 0 &&
- pe->FileHeader.NumberOfSections <= MAX_SECTIONS;
+ pe->FileHeader.NumberOfSections <= MAX_SECTIONS &&
+ IN_SET(pe->OptionalHeader.Magic, OPTHDR32_MAGIC, OPTHDR64_MAGIC);
}
static inline UINTN section_table_offset(const struct DosFileHeader *dos, const struct PeFileHeader *pe) {
@@ -182,15 +183,8 @@ EFI_STATUS pe_alignment_info(
return EFI_LOAD_ERROR;
*ret_entry_point_address = pe->OptionalHeader.AddressOfEntryPoint;
-
- if (pe->OptionalHeader.Magic == OPTHDR32_MAGIC) {
- *ret_size_of_image = pe->OptionalHeader.SizeOfImage;
- *ret_section_alignment = pe->OptionalHeader.SectionAlignment;
- } else if (pe->OptionalHeader.Magic == OPTHDR64_MAGIC) {
- *ret_size_of_image = pe->OptionalHeader.SizeOfImage;
- *ret_section_alignment = pe->OptionalHeader.SectionAlignment;
- } else
- return EFI_UNSUPPORTED;
+ *ret_size_of_image = pe->OptionalHeader.SizeOfImage;
+ *ret_section_alignment = pe->OptionalHeader.SectionAlignment;
return EFI_SUCCESS;
}
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
index 256aa21827..4de23792b5 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
@@ -154,7 +154,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
_SECTION_MAX,
};
- const CHAR8* const sections[] = {
+ static const CHAR8* const sections[_SECTION_MAX + 1] = {
[SECTION_CMDLINE] = (const CHAR8*) ".cmdline",
[SECTION_LINUX] = (const CHAR8*) ".linux",
[SECTION_INITRD] = (const CHAR8*) ".initrd",
@@ -172,6 +172,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
UINTN addrs[_SECTION_MAX] = {};
UINTN szs[_SECTION_MAX] = {};
CHAR8 *cmdline = NULL;
+ _cleanup_freepool_ CHAR8 *cmdline_owned = NULL;
EFI_STATUS err;
InitializeLib(image, sys_table);
@@ -187,8 +188,11 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
err = pe_memory_locate_sections(loaded_image->ImageBase, (const CHAR8**) sections, addrs, szs);
- if (EFI_ERROR(err))
+ if (EFI_ERROR(err) || szs[SECTION_LINUX] == 0) {
+ if (!EFI_ERROR(err))
+ err = EFI_NOT_FOUND;
return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
+ }
/* Show splash screen as early as possible */
graphics_splash((const UINT8*) loaded_image->ImageBase + addrs[SECTION_SPLASH], szs[SECTION_SPLASH], NULL);
@@ -201,18 +205,13 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
/* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */
if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 &&
*(CHAR16 *) loaded_image->LoadOptions > 0x1F) {
- CHAR16 *options;
- CHAR8 *line;
-
- options = (CHAR16 *)loaded_image->LoadOptions;
cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8);
- line = AllocatePool(cmdline_len);
- if (!line)
+ cmdline = cmdline_owned = AllocatePool(cmdline_len);
+ if (!cmdline)
return log_oom();
for (UINTN i = 0; i < cmdline_len; i++)
- line[i] = options[i];
- cmdline = line;
+ cmdline[i] = ((CHAR16 *) loaded_image->LoadOptions)[i];
/* Let's measure the passed kernel command line into the TPM. Note that this possibly
* duplicates what we already did in the boot menu, if that was already used. However, since
diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c
index 9128c507c8..4d981ca7e5 100644
--- a/src/boot/efi/util.c
+++ b/src/boot/efi/util.c
@@ -493,14 +493,21 @@ void log_error_stall(const CHAR16 *fmt, ...) {
assert(fmt);
+ INT32 attr = ST->ConOut->Mode->Attribute;
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK);
- Print(L"\n");
+ if (ST->ConOut->Mode->CursorColumn > 0)
+ Print(L"\n");
+
va_start(args, fmt);
VPrint(fmt, args);
va_end(args);
+
Print(L"\n");
+ ST->ConOut->SetAttribute(ST->ConOut, attr);
+
+ /* Give the user a chance to see the message. */
BS->Stall(3 * 1000 * 1000);
}
@@ -734,7 +741,7 @@ EFI_STATUS open_directory(
err = get_file_info_harder(dir, &file_info, NULL);
if (EFI_ERROR(err))
return err;
- if (!(file_info->Attribute & EFI_FILE_DIRECTORY))
+ if (!FLAGS_SET(file_info->Attribute, EFI_FILE_DIRECTORY))
return EFI_LOAD_ERROR;
*ret = TAKE_PTR(dir);
diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h
index ed527adb77..44af0bd0a0 100644
--- a/src/fundamental/macro-fundamental.h
+++ b/src/fundamental/macro-fundamental.h
@@ -306,3 +306,10 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
(l <= SIZE_MAX - (ali - 1)), /* overflow? */ \
((l) + (ali) - 1) & ~((ali) - 1), \
VOID_0)
+
+#define UPDATE_FLAG(orig, flag, b) \
+ ((b) ? ((orig) | (flag)) : ((orig) & ~(flag)))
+#define SET_FLAG(v, flag, b) \
+ (v) = UPDATE_FLAG(v, flag, b)
+#define FLAGS_SET(v, flags) \
+ ((~(v) & (flags)) == 0)