diff --git a/README b/README index 3811abfe06..3e75e44353 100644 --- a/README +++ b/README @@ -202,6 +202,7 @@ REQUIREMENTS: gcc, awk, sed, grep, and similar tools clang >= 10.0, llvm >= 10.0 (optional, required to build BPF programs from source code in C) + gnu-efi >= 3.0.5 (optional, required for systemd-boot) During runtime, you need the following additional dependencies: diff --git a/src/basic/macro.h b/src/basic/macro.h index c05339832d..03a0d061b8 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -145,24 +145,6 @@ #define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p))) #define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p))) -static inline size_t ALIGN_TO(size_t l, size_t ali) { - /* Check that alignment is exponent of 2 */ -#if SIZE_MAX == UINT_MAX - assert(__builtin_popcount(ali) == 1); -#elif SIZE_MAX == ULONG_MAX - assert(__builtin_popcountl(ali) == 1); -#elif SIZE_MAX == ULLONG_MAX - assert(__builtin_popcountll(ali) == 1); -#else -#error "Unexpected size_t" -#endif - - if (l > SIZE_MAX - (ali - 1)) - return SIZE_MAX; /* indicate overflow */ - - return ((l + ali - 1) & ~(ali - 1)); -} - #define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali))) /* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */ diff --git a/src/boot/efi/assert.c b/src/boot/efi/assert.c index 350b2b0167..7a25526de2 100644 --- a/src/boot/efi/assert.c +++ b/src/boot/efi/assert.c @@ -7,9 +7,9 @@ #include "util.h" void efi_assert(const char *expr, const char *file, unsigned line, const char *function) { - log_error_stall(L"systemd-boot assertion '%a' failed at %a:%u, function %a(). Halting.", expr, file, line, function); - for (;;) - uefi_call_wrapper(BS->Stall, 1, 60 * 1000 * 1000); + log_error_stall(L"systemd-boot assertion '%a' failed at %a:%u, function %a(). Halting.", expr, file, line, function); + for (;;) + BS->Stall(60 * 1000 * 1000); } #endif diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 5fdf26240a..6c4ddb1939 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -19,8 +19,11 @@ #include "util.h" #include "xbootldr.h" -#ifndef EFI_OS_INDICATIONS_BOOT_TO_FW_UI -#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL +#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 comiler. */ + #error systemd-boot requires compilation with GNU_EFI_USE_MS_ABI defined. #endif #define TEXT_ATTR_SWAP(c) EFI_TEXT_ATTR(((c) & 0b11110000) >> 4, (c) & 0b1111) @@ -46,7 +49,7 @@ typedef struct { CHAR16 *devicetree; CHAR16 *options; CHAR16 key; - EFI_STATUS (*call)(VOID); + EFI_STATUS (*call)(void); BOOLEAN no_autoselect; BOOLEAN non_unique; UINTN tries_done; @@ -88,7 +91,7 @@ enum { TIMEOUT_TYPE_MAX = UINT32_MAX, }; -static VOID cursor_left(UINTN *cursor, UINTN *first) { +static void cursor_left(UINTN *cursor, UINTN *first) { assert(cursor); assert(first); @@ -98,7 +101,7 @@ static VOID cursor_left(UINTN *cursor, UINTN *first) { (*first)--; } -static VOID cursor_right( +static void cursor_right( UINTN *cursor, UINTN *first, UINTN x_max, @@ -127,11 +130,17 @@ static BOOLEAN line_edit( if (!line_in) line_in = L""; + size = StrLen(line_in) + 1024; line = AllocatePool(size * sizeof(CHAR16)); + if (!line) + return FALSE; + StrCpy(line, line_in); len = StrLen(line); print = AllocatePool((x_max+1) * sizeof(CHAR16)); + if (!print) + return FALSE; first = 0; cursor = 0; @@ -411,12 +420,22 @@ static CHAR16 *update_timeout_efivar(UINT32 *t, BOOLEAN inc) { } } -static VOID print_status(Config *config, CHAR16 *loaded_image_path) { +static void ps_string(const CHAR16 *fmt, const void *value) { + assert(fmt); + if (value) + Print(fmt, value); +} + +static void ps_bool(const CHAR16 *fmt, BOOLEAN value) { + assert(fmt); + Print(fmt, yes_no(value)); +} + +static void print_status(Config *config, CHAR16 *loaded_image_path) { UINT64 key; - UINTN timeout; - BOOLEAN modevar; - _cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL; UINTN x_max, y_max; + BOOLEAN setup_mode = FALSE; + _cleanup_freepool_ CHAR16 *device_part_uuid = NULL, *default_efivar = NULL; assert(config); assert(loaded_image_path); @@ -424,124 +443,104 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { clear_screen(COLOR_NORMAL); console_query_mode(&x_max, &y_max); - Print(L"systemd-boot version: " GIT_VERSION "\n"); - Print(L"architecture: " EFI_MACHINE_TYPE_NAME "\n"); - Print(L"loaded image: %s\n", loaded_image_path); - Print(L"UEFI specification: %d.%02d\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); - Print(L"firmware vendor: %s\n", ST->FirmwareVendor); - Print(L"firmware version: %d.%02d\n", ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); - Print(L"console mode: %d/%ld\n", ST->ConOut->Mode->Mode, ST->ConOut->Mode->MaxMode - 1LL); - Print(L"console size: %d x %d\n", x_max, y_max); - Print(L"SecureBoot: %s\n", yes_no(secure_boot_enabled())); + (void) efivar_get(LOADER_GUID, L"LoaderDevicePartUUID", &device_part_uuid); + (void) efivar_get(LOADER_GUID, L"LoaderEntryDefault", &default_efivar); + (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &setup_mode); - if (efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &modevar) == EFI_SUCCESS) - Print(L"SetupMode: %s\n", modevar ? L"setup" : L"user"); + /* We employ some unusual indentation here for readability. */ - if (shim_loaded()) - Print(L"Shim: present\n"); + ps_string(L" systemd-boot version: %a\n", GIT_VERSION); + ps_string(L" loaded image: %s\n", loaded_image_path); + ps_string(L" loader partition UUID: %s\n", device_part_uuid); + ps_string(L" architecture: %a\n", EFI_MACHINE_TYPE_NAME); + Print(L" UEFI specification: %u.%02u\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); + ps_string(L" firmware vendor: %s\n", ST->FirmwareVendor); + Print(L" firmware version: %u.%02u\n", ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); + Print(L" OS indications: %lu\n", get_os_indications_supported()); + ps_bool(L" secure boot: %s\n", secure_boot_enabled()); + ps_bool(L" setup mode: %s\n", setup_mode); + ps_bool(L" shim: %s\n", shim_loaded()); + Print(L" console mode: %d/%d (%lu x %lu)\n", ST->ConOut->Mode->Mode, ST->ConOut->Mode->MaxMode - 1LL, x_max, y_max); - Print(L"OsIndicationsSupported: %d\n", get_os_indications_supported()); + Print(L"\n--- Press any key to continue. ---\n\n"); + console_key_read(&key, UINT64_MAX); - Print(L"\n--- press key ---\n\n"); - console_key_read(&key, 0); - - Print(L"timeout: %u s\n", config->timeout_sec); - if (config->timeout_sec_efivar != TIMEOUT_UNSET) - Print(L"timeout (EFI var): %u s\n", config->timeout_sec_efivar); - if (config->timeout_sec_config != TIMEOUT_UNSET) - Print(L"timeout (config): %u s\n", config->timeout_sec_config); - if (config->entry_default_pattern) - Print(L"default pattern: '%s'\n", config->entry_default_pattern); - Print(L"editor: %s\n", yes_no(config->editor)); - Print(L"auto-entries: %s\n", yes_no(config->auto_entries)); - Print(L"auto-firmware: %s\n", yes_no(config->auto_firmware)); - - switch (config->random_seed_mode) { - case RANDOM_SEED_OFF: - Print(L"random-seed-mode: off\n"); - break; - case RANDOM_SEED_WITH_SYSTEM_TOKEN: - Print(L"random-seed-mode: with-system-token\n"); - break; - case RANDOM_SEED_ALWAYS: - Print(L"random-seed-mode: always\n"); - break; + switch (config->timeout_sec_config) { + case TIMEOUT_UNSET: + break; + case TIMEOUT_MENU_FORCE: + Print(L" timeout: menu-force\n"); break; + case TIMEOUT_MENU_HIDDEN: + Print(L" timeout: menu-hidden\n"); break; default: - ; + Print(L" timeout: %lu s\n", config->timeout_sec_config); } - Print(L"\n"); + switch (config->timeout_sec_efivar) { + case TIMEOUT_UNSET: + break; + case TIMEOUT_MENU_FORCE: + Print(L" timeout (EFI var): menu-force\n"); break; + case TIMEOUT_MENU_HIDDEN: + Print(L" timeout (EFI var): menu-hidden\n"); break; + default: + Print(L" timeout (EFI var): %lu s\n", config->timeout_sec_efivar); + } - Print(L"config entry count: %d\n", config->entry_count); - Print(L"entry selected idx: %d\n", config->idx_default); - if (config->idx_default_efivar >= 0) - Print(L"entry EFI var idx: %d\n", config->idx_default_efivar); - Print(L"\n"); + ps_string(L" default: %s\n", config->entry_default_pattern); + ps_string(L" default (one-shot): %s\n", config->entry_oneshot); + ps_string(L" default (EFI var): %s\n", default_efivar); + ps_bool(L" editor: %s\n", config->editor); + ps_bool(L" auto-entries: %s\n", config->auto_entries); + ps_bool(L" auto-firmware: %s\n", config->auto_firmware); + ps_string(L" random-seed-mode: %s\n", random_seed_modes_table[config->random_seed_mode]); - if (efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &timeout) == EFI_SUCCESS) - Print(L"LoaderConfigTimeout: %u\n", timeout); + switch (config->console_mode) { + case CONSOLE_MODE_AUTO: + Print(L" console-mode: %s\n", L"auto"); break; + case CONSOLE_MODE_KEEP: + Print(L" console-mode: %s\n", L"keep"); break; + case CONSOLE_MODE_FIRMWARE_MAX: + Print(L" console-mode: %s\n", L"max"); break; + default: + Print(L" console-mode: %ld\n", config->console_mode); break; + } - if (config->entry_oneshot) - Print(L"LoaderEntryOneShot: %s\n", config->entry_oneshot); - if (efivar_get(LOADER_GUID, L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS) - Print(L"LoaderDevicePartUUID: %s\n", partstr); - if (efivar_get(LOADER_GUID, L"LoaderEntryDefault", &defaultstr) == EFI_SUCCESS) - Print(L"LoaderEntryDefault: %s\n", defaultstr); + /* EFI var console mode is always a concrete value or unset. */ + if (config->console_mode_efivar != CONSOLE_MODE_KEEP) + Print(L"console-mode (EFI var): %ld\n", config->console_mode_efivar); - Print(L"\n--- press key ---\n\n"); - console_key_read(&key, 0); + Print(L"\n--- Press any key to continue. ---\n\n"); + console_key_read(&key, UINT64_MAX); for (UINTN i = 0; i < config->entry_count; i++) { - ConfigEntry *entry; + ConfigEntry *entry = config->entries[i]; - if (key == KEYPRESS(0, SCAN_ESC, 0) || key == KEYPRESS(0, 0, 'q')) - break; + Print(L" config entry: %lu/%lu\n", i + 1, config->entry_count); + ps_string(L" id: %s\n", entry->id); + ps_string(L" title: %s\n", entry->title); + ps_string(L" title show: %s\n", streq_ptr(entry->title, entry->title_show) ? NULL : entry->title_show); + ps_string(L" version: %s\n", entry->version); + ps_string(L" machine-id: %s\n", entry->machine_id); + if (entry->device) + Print(L" device: %D\n", DevicePathFromHandle(entry->device)); + ps_string(L" loader: %s\n", entry->loader); + ps_string(L" devicetree: %s\n", entry->devicetree); + ps_string(L" options: %s\n", entry->options); + ps_bool(L" auto-select: %s\n", !entry->no_autoselect); + ps_bool(L" internal call: %s\n", !!entry->call); - entry = config->entries[i]; - Print(L"config entry: %d/%d\n", i+1, config->entry_count); - if (entry->id) - Print(L"id '%s'\n", entry->id); - Print(L"title show '%s'\n", entry->title_show); - if (entry->title) - Print(L"title '%s'\n", entry->title); - if (entry->version) - Print(L"version '%s'\n", entry->version); - if (entry->machine_id) - Print(L"machine-id '%s'\n", entry->machine_id); - if (entry->device) { - EFI_DEVICE_PATH *device_path; - - device_path = DevicePathFromHandle(entry->device); - if (device_path) { - _cleanup_freepool_ CHAR16 *str = NULL; - - str = DevicePathToStr(device_path); - Print(L"device handle '%s'\n", str); - } + ps_bool(L"counting boots: %s\n", entry->tries_left != UINTN_MAX); + if (entry->tries_left != UINTN_MAX) { + Print(L" tries: %lu done, %lu left\n", entry->tries_done, entry->tries_left); + Print(L" current path: %s\\%s\n", entry->path, entry->current_name); + Print(L" next path: %s\\%s\n", entry->path, entry->next_name); } - if (entry->loader) - Print(L"loader '%s'\n", entry->loader); - if (entry->devicetree) - Print(L"devicetree '%s'\n", entry->devicetree); - if (entry->options) - Print(L"options '%s'\n", entry->options); - Print(L"auto-select %s\n", yes_no(!entry->no_autoselect)); - if (entry->call) - Print(L"internal call yes\n"); - if (entry->tries_left != UINTN_MAX) - Print(L"counting boots yes\n" - "tries done %u\n" - "tries left %u\n" - "current path %s\\%s\n" - "next path %s\\%s\n", - entry->tries_done, - entry->tries_left, - entry->path, entry->current_name, - entry->path, entry->next_name); - - Print(L"\n--- press key ---\n\n"); - console_key_read(&key, 0); + Print(L"\n--- Press any key to continue, ESC or q to quit. ---\n\n"); + console_key_read(&key, UINT64_MAX); + if (key == KEYPRESS(0, SCAN_ESC, 0) || key == KEYPRESS(0, 0, 'q') || key == KEYPRESS(0, 0, 'Q')) + break; } } @@ -572,8 +571,8 @@ static BOOLEAN menu_run( INT64 console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar; graphics_mode(FALSE); - uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE); - uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE); + ST->ConIn->Reset(ST->ConIn, FALSE); + ST->ConOut->EnableCursor(ST->ConOut, FALSE); /* draw a single character to make ClearScreen work on some firmware */ Print(L" "); @@ -623,15 +622,25 @@ static BOOLEAN menu_run( /* Put status line after the entry list, but give it some breathing room. */ y_status = MIN(y_start + MIN(visible_max, config->entry_count) + 4, y_max - 1); - strv_free(lines); - FreePool(clearline); + lines = strv_free(lines); + clearline = mfree(clearline); /* menu entries title lines */ lines = AllocatePool((config->entry_count + 1) * sizeof(CHAR16 *)); + if (!lines) { + log_oom(); + return FALSE; + } + for (UINTN i = 0; i < config->entry_count; i++) { UINTN j, padding; lines[i] = AllocatePool(((line_width + 1) * sizeof(CHAR16))); + if (!lines[i]) { + log_oom(); + return FALSE; + } + padding = (line_width - MIN(StrLen(config->entries[i]->title_show), line_width)) / 2; for (j = 0; j < padding; j++) @@ -647,6 +656,11 @@ static BOOLEAN menu_run( lines[config->entry_count] = NULL; clearline = AllocatePool((x_max+1) * sizeof(CHAR16)); + if (!clearline) { + log_oom(); + return FALSE; + } + for (UINTN i = 0; i < x_max; i++) clearline[i] = ' '; clearline[x_max] = 0; @@ -699,11 +713,11 @@ static BOOLEAN menu_run( else x = 0; print_at(0, y_status, COLOR_NORMAL, clearline + (x_max - x)); - uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, status); - uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, clearline+1 + x + len); + ST->ConOut->OutputString(ST->ConOut, status); + ST->ConOut->OutputString(ST->ConOut, clearline + 1 + x + len); } - err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : 0); + err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : UINT64_MAX); if (err == EFI_TIMEOUT) { timeout_remain--; if (timeout_remain == 0) { @@ -922,7 +936,7 @@ static BOOLEAN menu_run( return run; } -static VOID config_add_entry(Config *config, ConfigEntry *entry) { +static void config_add_entry(Config *config, ConfigEntry *entry) { assert(config); assert(entry); @@ -930,13 +944,13 @@ static VOID config_add_entry(Config *config, ConfigEntry *entry) { UINTN i = config->entry_count + 16; config->entries = ReallocatePool( config->entries, - sizeof(VOID *) * config->entry_count, - sizeof(VOID *) * i); + sizeof(void *) * config->entry_count, + sizeof(void *) * i); } config->entries[config->entry_count++] = entry; } -static VOID config_entry_free(ConfigEntry *entry) { +static void config_entry_free(ConfigEntry *entry) { if (!entry) return; @@ -954,7 +968,7 @@ static VOID config_entry_free(ConfigEntry *entry) { FreePool(entry); } -static inline VOID config_entry_freep(ConfigEntry **entry) { +static inline void config_entry_freep(ConfigEntry **entry) { config_entry_free(*entry); } @@ -1031,7 +1045,7 @@ skip: return line; } -static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) { +static void config_defaults_load_from_file(Config *config, CHAR8 *content) { CHAR8 *line; UINTN pos = 0; CHAR8 *key, *value; @@ -1123,7 +1137,7 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) { } } -static VOID config_entry_parse_tries( +static void config_entry_parse_tries( ConfigEntry *entry, const CHAR16 *path, const CHAR16 *file, @@ -1242,16 +1256,15 @@ good: entry->next_name = PoolPrint(L"%s+%u-%u%s", prefix, next_left, next_done, suffix ?: L""); } -static VOID config_entry_bump_counters( +static void config_entry_bump_counters( ConfigEntry *entry, EFI_FILE_HANDLE root_dir) { _cleanup_freepool_ CHAR16* old_path = NULL, *new_path = NULL; _cleanup_(FileHandleClosep) EFI_FILE_HANDLE handle = NULL; - static const EFI_GUID EfiFileInfoGuid = EFI_FILE_INFO_ID; _cleanup_freepool_ EFI_FILE_INFO *file_info = NULL; UINTN file_info_size; - EFI_STATUS r; + EFI_STATUS err; assert(entry); assert(root_dir); @@ -1264,24 +1277,24 @@ static VOID config_entry_bump_counters( old_path = PoolPrint(L"%s\\%s", entry->path, entry->current_name); - r = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, old_path, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL); - if (EFI_ERROR(r)) + err = root_dir->Open(root_dir, &handle, old_path, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL); + if (EFI_ERROR(err)) return; - r = get_file_info_harder(handle, &file_info, &file_info_size); - if (EFI_ERROR(r)) + err = get_file_info_harder(handle, &file_info, &file_info_size); + if (EFI_ERROR(err)) return; /* And rename the file */ StrCpy(file_info->FileName, entry->next_name); - r = uefi_call_wrapper(handle->SetInfo, 4, handle, (EFI_GUID*) &EfiFileInfoGuid, file_info_size, file_info); - if (EFI_ERROR(r)) { - log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, r); + err = handle->SetInfo(handle, &GenericFileInfo, file_info_size, file_info); + if (EFI_ERROR(err)) { + log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, err); return; } /* Flush everything to disk, just in case… */ - (void) uefi_call_wrapper(handle->Flush, 1, handle); + (void) handle->Flush(handle); /* Let's tell the OS that we renamed this file, so that it knows what to rename to the counter-less name on * success */ @@ -1295,7 +1308,7 @@ static VOID config_entry_bump_counters( } } -static VOID config_entry_add_from_file( +static void config_entry_add_from_file( Config *config, EFI_HANDLE *device, EFI_FILE *root_dir, @@ -1418,10 +1431,10 @@ static VOID config_entry_add_from_file( return; /* check existence */ - err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, entry->loader, EFI_FILE_MODE_READ, 0ULL); + err = root_dir->Open(root_dir, &handle, entry->loader, EFI_FILE_MODE_READ, 0ULL); if (EFI_ERROR(err)) return; - uefi_call_wrapper(handle->Close, 1, handle); + handle->Close(handle); /* add initrd= to options */ if (entry->type == LOADER_LINUX && initrd) { @@ -1445,7 +1458,7 @@ static VOID config_entry_add_from_file( TAKE_PTR(entry); } -static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) { +static void config_load_defaults(Config *config, EFI_FILE *root_dir) { _cleanup_freepool_ CHAR8 *content = NULL; UINTN value; EFI_STATUS err; @@ -1488,7 +1501,7 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) { config->console_mode_efivar = value; } -static VOID config_load_entries( +static void config_load_entries( Config *config, EFI_HANDLE *device, EFI_FILE *root_dir, @@ -1565,7 +1578,7 @@ static INTN config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) { return 0; } -static VOID config_sort_entries(Config *config) { +static void config_sort_entries(Config *config) { assert(config); sort_pointer_array((void**) config->entries, config->entry_count, (compare_pointer_func_t) config_entry_compare); @@ -1582,7 +1595,7 @@ static INTN config_entry_find(Config *config, CHAR16 *id) { return -1; } -static VOID config_default_entry_select(Config *config) { +static void config_default_entry_select(Config *config) { _cleanup_freepool_ CHAR16 *entry_default = NULL; EFI_STATUS err; INTN i; @@ -1671,7 +1684,7 @@ static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) { } /* generate a unique title, avoiding non-distinguishable menu entries */ -static VOID config_title_generate(Config *config) { +static void config_title_generate(Config *config) { assert(config); /* set title */ @@ -1742,7 +1755,7 @@ static BOOLEAN config_entry_add_call( Config *config, const CHAR16 *id, const CHAR16 *title, - EFI_STATUS (*call)(VOID)) { + EFI_STATUS (*call)(void)) { ConfigEntry *entry; @@ -1864,10 +1877,10 @@ static BOOLEAN config_entry_add_loader_auto( } /* check existence */ - err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, (CHAR16*) loader, EFI_FILE_MODE_READ, 0ULL); + err = root_dir->Open(root_dir, &handle, (CHAR16*) loader, EFI_FILE_MODE_READ, 0ULL); if (EFI_ERROR(err)) return FALSE; - uefi_call_wrapper(handle->Close, 1, handle); + handle->Close(handle); entry = config_entry_add_loader(config, device, LOADER_UNDEFINED, id, key, title, loader, NULL); if (!entry) @@ -1879,7 +1892,7 @@ static BOOLEAN config_entry_add_loader_auto( return TRUE; } -static VOID config_entry_add_osx(Config *config) { +static void config_entry_add_osx(Config *config) { EFI_STATUS err; UINTN handle_count = 0; _cleanup_freepool_ EFI_HANDLE *handles = NULL; @@ -1900,14 +1913,14 @@ static VOID config_entry_add_osx(Config *config) { continue; found = config_entry_add_loader_auto(config, handles[i], root, NULL, L"auto-osx", 'a', L"macOS", L"\\System\\Library\\CoreServices\\boot.efi"); - uefi_call_wrapper(root->Close, 1, root); + root->Close(root); if (found) break; } } } -static VOID config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) { +static void config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) { _cleanup_freepool_ CHAR8 *bcd = NULL; const CHAR16 *title = NULL; EFI_STATUS err; @@ -1956,7 +1969,7 @@ static VOID config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FIL L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); } -static VOID config_entry_add_linux( +static void config_entry_add_linux( Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) { @@ -2091,7 +2104,7 @@ static VOID config_entry_add_linux( } } -static VOID config_load_xbootldr( +static void config_load_xbootldr( Config *config, EFI_HANDLE *device) { @@ -2129,7 +2142,7 @@ static EFI_STATUS image_start( if (!path) return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path."); - err = uefi_call_wrapper(BS->LoadImage, 6, FALSE, parent_image, path, NULL, 0, &image); + err = BS->LoadImage(FALSE, parent_image, path, NULL, 0, &image); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Error loading %s: %r", entry->loader, err); @@ -2148,8 +2161,8 @@ static EFI_STATUS image_start( if (options) { EFI_LOADED_IMAGE *loaded_image; - err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, - parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + err = BS->OpenProtocol(image, &LoadedImageProtocol, (void **)&loaded_image, + parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(err)) { log_error_stall(L"Error getting LoadedImageProtocol handle: %r", err); goto out_unload; @@ -2158,17 +2171,17 @@ static EFI_STATUS image_start( loaded_image->LoadOptionsSize = StrSize(loaded_image->LoadOptions); /* Try to log any options to the TPM, especially to catch manually edited options */ - (VOID) tpm_log_load_options(options); + (void) tpm_log_load_options(options); } efivar_set_time_usec(LOADER_GUID, L"LoaderTimeExecUSec", 0); - err = uefi_call_wrapper(BS->StartImage, 3, image, NULL, NULL); + err = BS->StartImage(image, NULL, NULL); out_unload: - uefi_call_wrapper(BS->UnloadImage, 1, image); + BS->UnloadImage(image); return err; } -static EFI_STATUS reboot_into_firmware(VOID) { +static EFI_STATUS reboot_into_firmware(void) { UINT64 old, new; EFI_STATUS err; @@ -2182,11 +2195,11 @@ static EFI_STATUS reboot_into_firmware(VOID) { if (EFI_ERROR(err)) return err; - err = uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS, 0, NULL); + err = RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); return log_error_status_stall(err, L"Error calling ResetSystem: %r", err); } -static VOID config_free(Config *config) { +static void config_free(Config *config) { assert(config); for (UINTN i = 0; i < config->entry_count; i++) config_entry_free(config->entries[i]); @@ -2196,7 +2209,7 @@ static VOID config_free(Config *config) { FreePool(config->entry_oneshot); } -static VOID config_write_entries_to_variable(Config *config) { +static void config_write_entries_to_variable(Config *config) { _cleanup_freepool_ CHAR8 *buffer = NULL; UINTN sz = 0; CHAR8 *p; @@ -2223,7 +2236,7 @@ static VOID config_write_entries_to_variable(Config *config) { (void) efivar_set_raw(LOADER_GUID, L"LoaderEntries", buffer, sz, 0); } -static VOID export_variables( +static void export_variables( EFI_LOADED_IMAGE *loaded_image, const CHAR16 *loaded_image_path, UINT64 init_usec) { @@ -2264,7 +2277,7 @@ static VOID export_variables( efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, 0); } -static VOID config_load_all_entries( +static void config_load_all_entries( Config *config, EFI_LOADED_IMAGE *loaded_image, const CHAR16 *loaded_image_path, @@ -2316,11 +2329,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { InitializeLib(image, sys_table); init_usec = time_usec(); - err = uefi_call_wrapper( - BS->OpenProtocol, 6, - image, + err = BS->OpenProtocol(image, &LoadedImageProtocol, - (VOID **)&loaded_image, + (void **)&loaded_image, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); @@ -2343,7 +2354,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { return log_error_status_stall(err, L"Error installing security policy: %r", err); } - (VOID) load_drivers(image, loaded_image, root_dir); + (void) load_drivers(image, loaded_image, root_dir); config_load_all_entries(&config, loaded_image, loaded_image_path, root_dir); @@ -2392,7 +2403,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { entry = config.entries[config.idx_default]; if (menu) { efivar_set_time_usec(LOADER_GUID, L"LoaderTimeMenuUSec", 0); - uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x10000, 0, NULL); if (!menu_run(&config, &entry, loaded_image_path)) break; } @@ -2406,12 +2416,11 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { config_entry_bump_counters(entry, root_dir); /* Export the selected boot entry to the system */ - (VOID) efivar_set(LOADER_GUID, L"LoaderEntrySelected", entry->id, 0); + (void) efivar_set(LOADER_GUID, L"LoaderEntrySelected", entry->id, 0); /* Optionally, read a random seed off the ESP and pass it to the OS */ - (VOID) process_random_seed(root_dir, config.random_seed_mode); + (void) process_random_seed(root_dir, config.random_seed_mode); - uefi_call_wrapper(BS->SetWatchdogTimer, 4, 5 * 60, 0x10000, 0, NULL); err = image_start(root_dir, image, &config, entry); if (EFI_ERROR(err)) { graphics_mode(FALSE); @@ -2424,6 +2433,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { } err = EFI_SUCCESS; out: - uefi_call_wrapper(BS->CloseProtocol, 4, image, &LoadedImageProtocol, image, NULL); + BS->CloseProtocol(image, &LoadedImageProtocol, image, NULL); return err; } diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c index b581c21bda..6b71e1e02c 100644 --- a/src/boot/efi/console.c +++ b/src/boot/efi/console.c @@ -12,14 +12,11 @@ #define VERTICAL_MAX_OK 1080 #define VIEWPORT_RATIO 10 -#define EFI_SIMPLE_TEXT_INPUT_EX_GUID \ - &(const EFI_GUID) EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID - static inline void EventClosep(EFI_EVENT *event) { if (!*event) return; - uefi_call_wrapper(BS->CloseEvent, 1, *event); + BS->CloseEvent(*event); } /* @@ -50,9 +47,8 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) { assert(key); if (!checked) { - err = LibLocateProtocol((EFI_GUID*) EFI_SIMPLE_TEXT_INPUT_EX_GUID, (VOID **)&TextInputEx); - if (EFI_ERROR(err) || - uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx) == EFI_INVALID_PARAMETER) + err = LibLocateProtocol(&SimpleTextInputExProtocol, (void **)&TextInputEx); + if (EFI_ERROR(err) || BS->CheckEvent(TextInputEx->WaitForKeyEx) == EFI_INVALID_PARAMETER) /* If WaitForKeyEx fails here, the firmware pretends it talks this * protocol, but it really doesn't. */ TextInputEx = NULL; @@ -62,33 +58,55 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) { checked = TRUE; } - if (timeout_usec > 0) { - err = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &timer); - if (EFI_ERROR(err)) - return log_error_status_stall(err, L"Error creating timer event: %r", err); + err = BS->CreateEvent(EVT_TIMER, 0, NULL, NULL, &timer); + if (EFI_ERROR(err)) + return log_error_status_stall(err, L"Error creating timer event: %r", err); + events[n_events++] = timer; + + /* Watchdog rearming loop in case the user never provides us with input or some + * broken firmware never returns from WaitForEvent. */ + for (;;) { + UINT64 watchdog_timeout_sec = 5 * 60, + watchdog_ping_usec = watchdog_timeout_sec / 2 * 1000 * 1000; /* SetTimer expects 100ns units for some reason. */ - err = uefi_call_wrapper(BS->SetTimer, 3, timer, TimerRelative, timeout_usec * 10); + err = BS->SetTimer( + timer, + TimerRelative, + MIN(timeout_usec, watchdog_ping_usec) * 10); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Error arming timer event: %r", err); - events[n_events++] = timer; + (void) BS->SetWatchdogTimer(watchdog_timeout_sec, 0x10000, 0, NULL); + err = BS->WaitForEvent(n_events, events, &index); + (void) BS->SetWatchdogTimer(watchdog_timeout_sec, 0x10000, 0, NULL); + + if (EFI_ERROR(err)) + return log_error_status_stall(err, L"Error waiting for events: %r", err); + + /* We have keyboard input, process it after this loop. */ + if (timer != events[index]) + break; + + /* The EFI timer fired instead. If this was a watchdog timeout, loop again. */ + if (timeout_usec == UINT64_MAX) + continue; + else if (timeout_usec > watchdog_ping_usec) { + timeout_usec -= watchdog_ping_usec; + continue; + } + + /* The caller requested a timeout? They shall have one! */ + return EFI_TIMEOUT; } - err = uefi_call_wrapper(BS->WaitForEvent, 3, n_events, events, &index); - if (EFI_ERROR(err)) - return log_error_status_stall(err, L"Error waiting for events: %r", err); - - if (timeout_usec > 0 && timer == events[index]) - return EFI_TIMEOUT; - /* TextInputEx might be ready too even if ConIn got to signal first. */ - if (TextInputEx && !EFI_ERROR(uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx))) { + if (TextInputEx && !EFI_ERROR(BS->CheckEvent(TextInputEx->WaitForKeyEx))) { EFI_KEY_DATA keydata; UINT64 keypress; UINT32 shift = 0; - err = uefi_call_wrapper(TextInputEx->ReadKeyStrokeEx, 2, TextInputEx, &keydata); + err = TextInputEx->ReadKeyStrokeEx(TextInputEx, &keydata); if (EFI_ERROR(err)) return err; @@ -110,7 +128,7 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) { return EFI_NOT_READY; } - err = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &k); + err = ST->ConIn->ReadKeyStroke(ST->ConIn, &k); if (EFI_ERROR(err)) return err; @@ -126,17 +144,17 @@ static EFI_STATUS change_mode(INT64 mode) { mode = CLAMP(mode, CONSOLE_MODE_RANGE_MIN, CONSOLE_MODE_RANGE_MAX); old_mode = MAX(CONSOLE_MODE_RANGE_MIN, ST->ConOut->Mode->Mode); - err = uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, mode); + err = ST->ConOut->SetMode(ST->ConOut, mode); if (!EFI_ERROR(err)) return EFI_SUCCESS; /* Something went wrong. Output is probably borked, so try to revert to previous mode. */ - if (!EFI_ERROR(uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, old_mode))) + if (!EFI_ERROR(ST->ConOut->SetMode(ST->ConOut, old_mode))) return err; /* Maybe the device is on fire? */ - uefi_call_wrapper(ST->ConOut->Reset, 2, ST->ConOut, TRUE); - uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, CONSOLE_MODE_RANGE_MIN); + ST->ConOut->Reset(ST->ConOut, TRUE); + ST->ConOut->SetMode(ST->ConOut, CONSOLE_MODE_RANGE_MIN); return err; } @@ -144,7 +162,7 @@ static INT64 get_auto_mode(void) { EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_STATUS err; - err = LibLocateProtocol(&GraphicsOutputProtocol, (VOID **)&GraphicsOutput); + err = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&GraphicsOutput); if (!EFI_ERROR(err) && GraphicsOutput->Mode && GraphicsOutput->Mode->Info) { EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info = GraphicsOutput->Mode->Info; BOOLEAN keep = FALSE; @@ -231,7 +249,7 @@ EFI_STATUS console_query_mode(UINTN *x_max, UINTN *y_max) { assert(x_max); assert(y_max); - err = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, x_max, y_max); + err = ST->ConOut->QueryMode(ST->ConOut, ST->ConOut->Mode->Mode, x_max, y_max); if (EFI_ERROR(err)) { /* Fallback values mandated by UEFI spec. */ switch (ST->ConOut->Mode->Mode) { diff --git a/src/boot/efi/cpio.c b/src/boot/efi/cpio.c index e20615633f..bffe4f638c 100644 --- a/src/boot/efi/cpio.c +++ b/src/boot/efi/cpio.c @@ -53,12 +53,12 @@ static CHAR8* pad4(CHAR8 *p, const CHAR8* start) { static EFI_STATUS pack_cpio_one( const CHAR16 *fname, - const VOID *contents, + const void *contents, UINTN contents_size, const CHAR8 *target_dir_prefix, UINT32 access_mode, UINT32 *inode_counter, - VOID **cpio_buffer, + void **cpio_buffer, UINTN *cpio_buffer_size) { UINTN l, target_dir_prefix_size, fname_size, q; @@ -167,7 +167,7 @@ static EFI_STATUS pack_cpio_dir( const CHAR8 *path, UINT32 access_mode, UINT32 *inode_counter, - VOID **cpio_buffer, + void **cpio_buffer, UINTN *cpio_buffer_size) { UINTN l, path_size; @@ -238,7 +238,7 @@ static EFI_STATUS pack_cpio_prefix( const CHAR8 *path, UINT32 dir_mode, UINT32 *inode_counter, - VOID **cpio_buffer, + void **cpio_buffer, UINTN *cpio_buffer_size) { EFI_STATUS err; @@ -278,7 +278,7 @@ static EFI_STATUS pack_cpio_prefix( } static EFI_STATUS pack_cpio_trailer( - VOID **cpio_buffer, + void **cpio_buffer, UINTN *cpio_buffer_size) { static const char trailer[] = @@ -298,7 +298,7 @@ static EFI_STATUS pack_cpio_trailer( "00000000" "TRAILER!!!\0\0\0"; /* There's a fourth NUL byte appended here, because this is a string */ - VOID *a; + void *a; /* Generates the cpio trailer record that indicates the end of our initrd cpio archive */ @@ -325,7 +325,7 @@ EFI_STATUS pack_cpio( UINT32 access_mode, UINTN tpm_pcr, const CHAR16 *tpm_description, - VOID **ret_buffer, + void **ret_buffer, UINTN *ret_buffer_size) { _cleanup_(FileHandleClosep) EFI_FILE_HANDLE root = NULL, extra_dir = NULL; @@ -333,7 +333,7 @@ EFI_STATUS pack_cpio( _cleanup_freepool_ CHAR16 *loaded_image_path = NULL, *j = NULL; _cleanup_freepool_ EFI_FILE_INFO *dirent = NULL; _cleanup_(strv_freep) CHAR16 **items = NULL; - _cleanup_freepool_ VOID *buffer = NULL; + _cleanup_freepool_ void *buffer = NULL; UINT32 inode = 1; /* inode counter, so that each item gets a new inode */ EFI_STATUS err; @@ -416,7 +416,7 @@ EFI_STATUS pack_cpio( /* Now, sort the files we found, to make this uniform and stable (and to ensure the TPM measurements * are not dependent on read order) */ - sort_pointer_array((VOID**) items, n_items, (compare_pointer_func_t) StrCmp); + sort_pointer_array((void**) items, n_items, (compare_pointer_func_t) StrCmp); /* Generate the leading directory inodes right before adding the first files, to the * archive. Otherwise the cpio archive cannot be unpacked, since the leading dirs won't exist. */ diff --git a/src/boot/efi/cpio.h b/src/boot/efi/cpio.h index 8a6d093122..7a2331e0c8 100644 --- a/src/boot/efi/cpio.h +++ b/src/boot/efi/cpio.h @@ -11,5 +11,5 @@ EFI_STATUS pack_cpio( UINT32 access_mode, UINTN pcr, const CHAR16 *tpm_description, - VOID **ret_buffer, + void **ret_buffer, UINTN *ret_buffer_size); diff --git a/src/boot/efi/devicetree.c b/src/boot/efi/devicetree.c index d8a279e826..30ba88c4f8 100644 --- a/src/boot/efi/devicetree.c +++ b/src/boot/efi/devicetree.c @@ -14,8 +14,7 @@ static EFI_STATUS devicetree_allocate(struct devicetree_state *state, UINTN size assert(state); - err = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiACPIReclaimMemory, pages, - &state->addr); + err = BS->AllocatePages(AllocateAnyPages, EfiACPIReclaimMemory, pages, &state->addr); if (EFI_ERROR(err)) return err; @@ -35,31 +34,31 @@ static EFI_STATUS devicetree_fixup(struct devicetree_state *state, UINTN len) { assert(state); - err = LibLocateProtocol(&EfiDtFixupProtocol, (VOID **)&fixup); + err = LibLocateProtocol(&EfiDtFixupProtocol, (void **)&fixup); if (EFI_ERROR(err)) return log_error_status_stall(EFI_SUCCESS, L"Could not locate device tree fixup protocol, skipping."); size = devicetree_allocated(state); - err = uefi_call_wrapper(fixup->Fixup, 4, fixup, PHYSICAL_ADDRESS_TO_POINTER(state->addr), &size, - EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY); + err = fixup->Fixup(fixup, PHYSICAL_ADDRESS_TO_POINTER(state->addr), &size, + EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY); if (err == EFI_BUFFER_TOO_SMALL) { EFI_PHYSICAL_ADDRESS oldaddr = state->addr; UINTN oldpages = state->pages; - VOID *oldptr = PHYSICAL_ADDRESS_TO_POINTER(state->addr); + void *oldptr = PHYSICAL_ADDRESS_TO_POINTER(state->addr); err = devicetree_allocate(state, size); if (EFI_ERROR(err)) return err; CopyMem(PHYSICAL_ADDRESS_TO_POINTER(state->addr), oldptr, len); - err = uefi_call_wrapper(BS->FreePages, 2, oldaddr, oldpages); + err = BS->FreePages(oldaddr, oldpages); if (EFI_ERROR(err)) return err; size = devicetree_allocated(state); - err = uefi_call_wrapper(fixup->Fixup, 4, fixup, PHYSICAL_ADDRESS_TO_POINTER(state->addr), &size, - EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY); + err = fixup->Fixup(fixup, PHYSICAL_ADDRESS_TO_POINTER(state->addr), &size, + EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY); } return err; @@ -80,8 +79,7 @@ EFI_STATUS devicetree_install(struct devicetree_state *state, if (EFI_ERROR(err)) return EFI_UNSUPPORTED; - err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, name, EFI_FILE_MODE_READ, - EFI_FILE_READ_ONLY); + err = root_dir->Open(root_dir, &handle, name, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY); if (EFI_ERROR(err)) return err; @@ -98,7 +96,7 @@ EFI_STATUS devicetree_install(struct devicetree_state *state, if (EFI_ERROR(err)) return err; - err = uefi_call_wrapper(handle->Read, 3, handle, &len, PHYSICAL_ADDRESS_TO_POINTER(state->addr)); + err = handle->Read(handle, &len, PHYSICAL_ADDRESS_TO_POINTER(state->addr)); if (EFI_ERROR(err)) return err; @@ -106,11 +104,11 @@ EFI_STATUS devicetree_install(struct devicetree_state *state, if (EFI_ERROR(err)) return err; - return uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr)); + return BS->InstallConfigurationTable(&EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr)); } EFI_STATUS devicetree_install_from_memory(struct devicetree_state *state, - const VOID *dtb_buffer, UINTN dtb_length) { + const void *dtb_buffer, UINTN dtb_length) { EFI_STATUS err; @@ -131,7 +129,7 @@ EFI_STATUS devicetree_install_from_memory(struct devicetree_state *state, if (EFI_ERROR(err)) return err; - return uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr)); + return BS->InstallConfigurationTable(&EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr)); } void devicetree_cleanup(struct devicetree_state *state) { @@ -140,11 +138,11 @@ void devicetree_cleanup(struct devicetree_state *state) { if (!state->pages) return; - err = uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, state->orig); + err = BS->InstallConfigurationTable(&EfiDtbTableGuid, state->orig); /* don't free the current device tree if we can't reinstate the old one */ if (EFI_ERROR(err)) return; - uefi_call_wrapper(BS->FreePages, 2, state->addr, state->pages); + BS->FreePages(state->addr, state->pages); state->pages = 0; } diff --git a/src/boot/efi/devicetree.h b/src/boot/efi/devicetree.h index 25f93f97f9..fa8a1be6ed 100644 --- a/src/boot/efi/devicetree.h +++ b/src/boot/efi/devicetree.h @@ -4,7 +4,7 @@ struct devicetree_state { EFI_PHYSICAL_ADDRESS addr; UINTN pages; - VOID *orig; + void *orig; }; EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE_HANDLE root_dir, CHAR16 *name); diff --git a/src/boot/efi/drivers.c b/src/boot/efi/drivers.c index a876c3df7f..f25b35ac96 100644 --- a/src/boot/efi/drivers.c +++ b/src/boot/efi/drivers.c @@ -6,9 +6,9 @@ #include "drivers.h" #include "util.h" -static VOID efi_unload_image(EFI_HANDLE *h) { +static void efi_unload_image(EFI_HANDLE *h) { if (*h) - (VOID) uefi_call_wrapper(BS->UnloadImage, 1, *h); + (void) BS->UnloadImage(*h); } static EFI_STATUS load_one_driver( @@ -33,21 +33,11 @@ static EFI_STATUS load_one_driver( if (!path) return log_oom(); - err = uefi_call_wrapper( - BS->LoadImage, 6, - FALSE, - parent_image, - path, - NULL, 0, - &image); + err = BS->LoadImage(FALSE, parent_image, path, NULL, 0, &image); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to load image %s: %r", fname, err); - err = uefi_call_wrapper( - BS->HandleProtocol, 3, - image, - &LoadedImageProtocol, - (VOID **)&loaded_image); + err = BS->HandleProtocol(image, &LoadedImageProtocol, (void **)&loaded_image); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to find protocol in driver image s: %r", fname, err); @@ -55,11 +45,7 @@ static EFI_STATUS load_one_driver( loaded_image->ImageCodeType != EfiRuntimeServicesCode) return log_error_status_stall(EFI_INVALID_PARAMETER, L"Image %s is not a driver, refusing: %r", fname); - err = uefi_call_wrapper( - BS->StartImage, 3, - image, - NULL, - NULL); + err = BS->StartImage(image, NULL, NULL); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to start image %s: %r", fname, err); @@ -67,30 +53,19 @@ static EFI_STATUS load_one_driver( return EFI_SUCCESS; } -static EFI_STATUS reconnect(VOID) { +static EFI_STATUS reconnect(void) { _cleanup_freepool_ EFI_HANDLE *handles = NULL; UINTN n_handles = 0; EFI_STATUS err; /* Reconnects all handles, so that any loaded drivers can take effect. */ - err = uefi_call_wrapper( - BS->LocateHandleBuffer, 5, - AllHandles, - NULL, - NULL, - &n_handles, - &handles); + err = BS->LocateHandleBuffer(AllHandles, NULL, NULL, &n_handles, &handles); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to get list of handles: %r", err); for (UINTN i = 0; i < n_handles; i++) { - err = uefi_call_wrapper( - BS->ConnectController, 4, - handles[i], - NULL, - NULL, - TRUE); + err = BS->ConnectController(handles[i], NULL, NULL, TRUE); if (err == EFI_NOT_FOUND) /* No drivers for this handle */ continue; if (EFI_ERROR(err)) @@ -144,7 +119,7 @@ EFI_STATUS load_drivers( } if (n_succeeded > 0) - (VOID) reconnect(); + (void) reconnect(); return EFI_SUCCESS; } diff --git a/src/boot/efi/graphics.c b/src/boot/efi/graphics.c index a7a99b3448..62a3512fa3 100644 --- a/src/boot/efi/graphics.c +++ b/src/boot/efi/graphics.c @@ -19,13 +19,13 @@ EFI_STATUS graphics_mode(BOOLEAN on) { BOOLEAN stdin_locked; EFI_STATUS err; - err = LibLocateProtocol((EFI_GUID*) EFI_CONSOLE_CONTROL_GUID, (VOID **)&ConsoleControl); + err = LibLocateProtocol((EFI_GUID*) EFI_CONSOLE_CONTROL_GUID, (void **)&ConsoleControl); if (EFI_ERROR(err)) /* console control protocol is nonstandard and might not exist. */ return err == EFI_NOT_FOUND ? EFI_SUCCESS : err; /* check current mode */ - err = uefi_call_wrapper(ConsoleControl->GetMode, 4, ConsoleControl, ¤t, &uga_exists, &stdin_locked); + err =ConsoleControl->GetMode(ConsoleControl, ¤t, &uga_exists, &stdin_locked); if (EFI_ERROR(err)) return err; @@ -34,10 +34,10 @@ EFI_STATUS graphics_mode(BOOLEAN on) { if (new == current) return EFI_SUCCESS; - err = uefi_call_wrapper(ConsoleControl->SetMode, 2, ConsoleControl, new); + err =ConsoleControl->SetMode(ConsoleControl, new); /* some firmware enables the cursor when switching modes */ - uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE); + ST->ConOut->EnableCursor(ST->ConOut, FALSE); return err; } diff --git a/src/boot/efi/initrd.c b/src/boot/efi/initrd.c index 055670f239..b302743adf 100644 --- a/src/boot/efi/initrd.c +++ b/src/boot/efi/initrd.c @@ -10,7 +10,7 @@ /* extend LoadFileProtocol */ struct initrd_loader { EFI_LOAD_FILE_PROTOCOL load_file; - const VOID *address; + const void *address; UINTN length; }; @@ -41,7 +41,7 @@ EFIAPI EFI_STATUS initrd_load_file( EFI_DEVICE_PATH *file_path, BOOLEAN boot_policy, UINTN *buffer_size, - VOID *buffer) { + void *buffer) { struct initrd_loader *loader; @@ -66,7 +66,7 @@ EFIAPI EFI_STATUS initrd_load_file( } EFI_STATUS initrd_register( - const VOID *initrd_address, + const void *initrd_address, UINTN initrd_length, EFI_HANDLE *ret_initrd_handle) { @@ -84,7 +84,7 @@ EFI_STATUS initrd_register( LocateDevicePath checks for the "closest DevicePath" and returns its handle, where as InstallMultipleProtocolInterfaces only maches identical DevicePaths. */ - err = uefi_call_wrapper(BS->LocateDevicePath, 3, &EfiLoadFile2Protocol, &dp, &handle); + err = BS->LocateDevicePath(&EfiLoadFile2Protocol, &dp, &handle); if (err != EFI_NOT_FOUND) /* InitrdMedia is already registered */ return EFI_ALREADY_STARTED; @@ -99,8 +99,7 @@ EFI_STATUS initrd_register( }; /* create a new handle and register the LoadFile2 protocol with the InitrdMediaPath on it */ - err = uefi_call_wrapper( - BS->InstallMultipleProtocolInterfaces, 8, + err = BS->InstallMultipleProtocolInterfaces( ret_initrd_handle, &DevicePathProtocol, &efi_initrd_device_path, &EfiLoadFile2Protocol, loader, @@ -119,21 +118,17 @@ EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle) { return EFI_SUCCESS; /* get the LoadFile2 protocol that we allocated earlier */ - err = uefi_call_wrapper( - BS->OpenProtocol, 6, - initrd_handle, &EfiLoadFile2Protocol, (VOID **) &loader, + err = BS->OpenProtocol( + initrd_handle, &EfiLoadFile2Protocol, (void **) &loader, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(err)) return err; /* close the handle */ - (void) uefi_call_wrapper( - BS->CloseProtocol, 4, - initrd_handle, &EfiLoadFile2Protocol, NULL, NULL); + (void) BS->CloseProtocol(initrd_handle, &EfiLoadFile2Protocol, NULL, NULL); /* uninstall all protocols thus destroying the handle */ - err = uefi_call_wrapper( - BS->UninstallMultipleProtocolInterfaces, 6, + err = BS->UninstallMultipleProtocolInterfaces( initrd_handle, &DevicePathProtocol, &efi_initrd_device_path, &EfiLoadFile2Protocol, loader, diff --git a/src/boot/efi/initrd.h b/src/boot/efi/initrd.h index bb3a334786..b26a81e369 100644 --- a/src/boot/efi/initrd.h +++ b/src/boot/efi/initrd.h @@ -4,7 +4,7 @@ #include EFI_STATUS initrd_register( - const VOID *initrd_address, + const void *initrd_address, UINTN initrd_length, EFI_HANDLE *ret_initrd_handle); diff --git a/src/boot/efi/linux.c b/src/boot/efi/linux.c index 98f1db24e0..f86fcc1143 100644 --- a/src/boot/efi/linux.c +++ b/src/boot/efi/linux.c @@ -25,7 +25,7 @@ static EFI_LOADED_IMAGE * loaded_image_free(EFI_LOADED_IMAGE *img) { static EFI_STATUS loaded_image_register( const CHAR8 *cmdline, UINTN cmdline_len, - const VOID *linux_buffer, UINTN linux_length, + const void *linux_buffer, UINTN linux_length, EFI_HANDLE *ret_image) { EFI_LOADED_IMAGE *loaded_image = NULL; @@ -42,7 +42,7 @@ static EFI_STATUS loaded_image_register( /* provide the image base address and size */ *loaded_image = (EFI_LOADED_IMAGE) { - .ImageBase = (VOID *) linux_buffer, + .ImageBase = (void *) linux_buffer, .ImageSize = linux_length }; @@ -57,7 +57,7 @@ static EFI_STATUS loaded_image_register( } /* install a new LoadedImage protocol. ret_handle is a new image handle */ - err = uefi_call_wrapper(BS->InstallMultipleProtocolInterfaces, 4, + err = BS->InstallMultipleProtocolInterfaces( ret_image, &LoadedImageProtocol, loaded_image, NULL); @@ -75,18 +75,15 @@ static EFI_STATUS loaded_image_unregister(EFI_HANDLE loaded_image_handle) { return EFI_SUCCESS; /* get the LoadedImage protocol that we allocated earlier */ - err = uefi_call_wrapper( - BS->OpenProtocol, 6, - loaded_image_handle, &LoadedImageProtocol, (VOID **) &loaded_image, + err = BS->OpenProtocol( + loaded_image_handle, &LoadedImageProtocol, (void **) &loaded_image, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(err)) return err; /* close the handle */ - (void) uefi_call_wrapper( - BS->CloseProtocol, 4, - loaded_image_handle, &LoadedImageProtocol, NULL, NULL); - err = uefi_call_wrapper(BS->UninstallMultipleProtocolInterfaces, 4, + (void) BS->CloseProtocol(loaded_image_handle, &LoadedImageProtocol, NULL, NULL); + err = BS->UninstallMultipleProtocolInterfaces( loaded_image_handle, &LoadedImageProtocol, loaded_image, NULL); @@ -117,21 +114,21 @@ struct pages { static inline void cleanup_pages(struct pages *p) { if (p->addr == 0) return; - (void) uefi_call_wrapper(BS->FreePages, 2, p->addr, p->num); + (void) BS->FreePages(p->addr, p->num); } EFI_STATUS linux_exec( EFI_HANDLE image, const CHAR8 *cmdline, UINTN cmdline_len, - const VOID *linux_buffer, UINTN linux_length, - const VOID *initrd_buffer, UINTN initrd_length) { + const void *linux_buffer, UINTN linux_length, + const void *initrd_buffer, UINTN initrd_length) { _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL; _cleanup_(cleanup_loaded_image) EFI_HANDLE loaded_image_handle = NULL; UINT32 kernel_alignment, kernel_size_of_image, kernel_entry_address; EFI_IMAGE_ENTRY_POINT kernel_entry; _cleanup_(cleanup_pages) struct pages kernel = {}; - VOID *new_buffer; + void *new_buffer; EFI_STATUS err; assert(image); @@ -157,10 +154,7 @@ EFI_STATUS linux_exec( */ /* allocate SizeOfImage + SectionAlignment because the new_buffer can move up to Alignment-1 bytes */ kernel.num = EFI_SIZE_TO_PAGES(ALIGN_TO(kernel_size_of_image, kernel_alignment) + kernel_alignment); - err = uefi_call_wrapper( - BS->AllocatePages, 4, - AllocateAnyPages, EfiLoaderData, - kernel.num, &kernel.addr); + err = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, kernel.num, &kernel.addr); if (EFI_ERROR(err)) return EFI_OUT_OF_RESOURCES; new_buffer = PHYSICAL_ADDRESS_TO_POINTER(ALIGN_TO(kernel.addr, kernel_alignment)); @@ -182,5 +176,5 @@ EFI_STATUS linux_exec( return err; /* call the kernel */ - return uefi_call_wrapper(kernel_entry, 2, loaded_image_handle, ST); + return kernel_entry(loaded_image_handle, ST); } diff --git a/src/boot/efi/linux.h b/src/boot/efi/linux.h index e030e4f31e..c4bf18c10b 100644 --- a/src/boot/efi/linux.h +++ b/src/boot/efi/linux.h @@ -6,5 +6,5 @@ EFI_STATUS linux_exec( EFI_HANDLE image, const CHAR8 *cmdline, UINTN cmdline_len, - const VOID *linux_buffer, UINTN linux_length, - const VOID *initrd_buffer, UINTN initrd_length); + const void *linux_buffer, UINTN linux_length, + const void *initrd_buffer, UINTN initrd_length); diff --git a/src/boot/efi/linux_x86.c b/src/boot/efi/linux_x86.c index 539ad72363..98b2366ad2 100644 --- a/src/boot/efi/linux_x86.c +++ b/src/boot/efi/linux_x86.c @@ -104,9 +104,9 @@ struct boot_params { #define __regparm0__ #endif -typedef VOID(*handover_f)(VOID *image, EFI_SYSTEM_TABLE *table, struct boot_params *params) __regparm0__; +typedef void(*handover_f)(void *image, EFI_SYSTEM_TABLE *table, struct boot_params *params) __regparm0__; -static VOID linux_efi_handover(EFI_HANDLE image, struct boot_params *params) { +static void linux_efi_handover(EFI_HANDLE image, struct boot_params *params) { handover_f handover; UINTN start = (UINTN)params->hdr.code32_start; @@ -123,8 +123,8 @@ static VOID linux_efi_handover(EFI_HANDLE image, struct boot_params *params) { EFI_STATUS linux_exec( EFI_HANDLE image, const CHAR8 *cmdline, UINTN cmdline_len, - const VOID *linux_buffer, UINTN linux_length, - const VOID *initrd_buffer, UINTN initrd_length) { + const void *linux_buffer, UINTN linux_length, + const void *initrd_buffer, UINTN initrd_length) { const struct boot_params *image_params; struct boot_params *boot_params; @@ -147,8 +147,7 @@ EFI_STATUS linux_exec( return EFI_LOAD_ERROR; addr = UINT32_MAX; /* Below the 32bit boundary */ - err = uefi_call_wrapper( - BS->AllocatePages, 4, + err = BS->AllocatePages( AllocateMaxAddress, EfiLoaderData, EFI_SIZE_TO_PAGES(0x4000), @@ -166,8 +165,7 @@ EFI_STATUS linux_exec( if (cmdline) { addr = 0xA0000; - err = uefi_call_wrapper( - BS->AllocatePages, 4, + err = BS->AllocatePages( AllocateMaxAddress, EfiLoaderData, EFI_SIZE_TO_PAGES(cmdline_len + 1), diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index de7856bacf..220a8fbb35 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -37,8 +37,7 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log( }; CopyMem(tcg_event->Event, description, desc_len); - return uefi_call_wrapper( - tcg->HashLogExtendEvent, 7, + return tcg->HashLogExtendEvent( (EFI_TCG *) tcg, buffer, buffer_size, TCG_ALG_SHA, @@ -75,8 +74,7 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log( CopyMem(tcg_event->Event, description, desc_len); - return uefi_call_wrapper( - tcg->HashLogExtendEvent, 5, + return tcg->HashLogExtendEvent( tcg, 0, buffer, buffer_size, @@ -96,8 +94,7 @@ static EFI_TCG *tcg1_interface_check(void) { if (EFI_ERROR(status)) return NULL; - status = uefi_call_wrapper( - tcg->StatusCheck, 5, + status = tcg->StatusCheck( tcg, &capability, &features, @@ -126,7 +123,7 @@ static EFI_TCG2 * tcg2_interface_check(void) { if (EFI_ERROR(status)) return NULL; - status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, &capability); + status = tcg->GetCapability(tcg, &capability); if (EFI_ERROR(status)) return NULL; diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index e3e13fec04..e6bb7d7c6a 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -93,6 +93,14 @@ if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false' endif have_gnu_efi = gnu_efi_path_arch != '' and efi_libdir != '' + + if have_gnu_efi and not cc.has_header_symbol('efi.h', 'EFI_IMAGE_MACHINE_X64', + include_directories: include_directories(efi_incdir, efi_incdir / gnu_efi_path_arch)) + have_gnu_efi = false + if get_option('gnu-efi') == 'true' + error('gnu-efi support requested, but found headers are too old (3.0.5+ required)') + endif + endif else have_gnu_efi = false endif @@ -205,6 +213,7 @@ if have_gnu_efi '-isystem', efi_incdir / gnu_efi_path_arch, '-I', fundamental_path, '-DSD_BOOT', + '-DGNU_EFI_USE_MS_ABI', '-include', efi_config_h, '-include', version_h, ] @@ -216,9 +225,7 @@ if have_gnu_efi if efi_arch == 'x86_64' compile_args += ['-mno-red-zone', '-mno-sse', - '-mno-mmx', - '-DEFI_FUNCTION_WRAPPER', - '-DGNU_EFI_USE_MS_ABI'] + '-mno-mmx'] elif efi_arch == 'ia32' compile_args += ['-mno-sse', '-mno-mmx'] diff --git a/src/boot/efi/missing_efi.h b/src/boot/efi/missing_efi.h index e3e0b978ef..b0bd00365f 100644 --- a/src/boot/efi/missing_efi.h +++ b/src/boot/efi/missing_efi.h @@ -5,61 +5,12 @@ #include "macro-fundamental.h" -#ifndef EFI_RNG_PROTOCOL_GUID - -#define EFI_RNG_PROTOCOL_GUID \ - { 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44} } - -typedef EFI_GUID EFI_RNG_ALGORITHM; - -#define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \ - {0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96} } - -#define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \ - {0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7} } - -#define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \ - {0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e} } - -#define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \ - {0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46} } - -#define EFI_RNG_ALGORITHM_X9_31_AES_GUID \ - {0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9} } - -#define EFI_RNG_ALGORITHM_RAW \ - {0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61} } - -INTERFACE_DECL(_EFI_RNG_PROTOCOL); - -typedef -EFI_STATUS -(EFIAPI *EFI_RNG_GET_INFO) ( - IN struct _EFI_RNG_PROTOCOL *This, - IN OUT UINTN *RNGAlgorithmListSize, - OUT EFI_RNG_ALGORITHM *RNGAlgorithmList -); - -typedef -EFI_STATUS -(EFIAPI *EFI_RNG_GET_RNG) ( - IN struct _EFI_RNG_PROTOCOL *This, - IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL - IN UINTN RNGValueLength, - OUT UINT8 *RNGValue -); - -typedef struct _EFI_RNG_PROTOCOL { - EFI_RNG_GET_INFO GetInfo; - EFI_RNG_GET_RNG GetRNG; -} EFI_RNG_PROTOCOL; - -#endif - +/* gnu-efi 3.0.13 */ #ifndef EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID #define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ { 0xdd9e7534, 0x7762, 0x4698, {0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa} } +#define SimpleTextInputExProtocol ((EFI_GUID)EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID) #define EFI_SHIFT_STATE_VALID 0x80000000 #define EFI_RIGHT_CONTROL_PRESSED 0x00000004 @@ -123,10 +74,12 @@ typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL { #endif +/* gnu-efi 3.0.14 */ #ifndef EFI_IMAGE_MACHINE_RISCV64 #define EFI_IMAGE_MACHINE_RISCV64 0x5064 #endif +/* gnu-efi 3.0.14 */ #ifndef EFI_DTB_TABLE_GUID #define EFI_DTB_TABLE_GUID \ { 0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0} } @@ -163,6 +116,7 @@ struct _EFI_DT_FIXUP_PROTOCOL { #endif +/* TCG EFI Protocol Specification */ #ifndef EFI_TCG_GUID #define EFI_TCG_GUID \ @@ -262,6 +216,7 @@ typedef struct _EFI_TCG { #endif +/* TCG EFI Protocol Specification */ #ifndef EFI_TCG2_GUID #define EFI_TCG2_GUID \ diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c index 1309eb13a2..6aecfe4526 100644 --- a/src/boot/efi/pe.c +++ b/src/boot/efi/pe.c @@ -3,6 +3,7 @@ #include #include +#include "missing_efi.h" #include "pe.h" #include "util.h" @@ -130,7 +131,7 @@ static inline UINTN section_table_offset(const struct DosFileHeader *dos, const return dos->ExeHeader + OFFSETOF(struct PeFileHeader, OptionalHeader) + pe->FileHeader.SizeOfOptionalHeader; } -static VOID locate_sections( +static void locate_sections( const struct PeSectionHeader section_table[], UINTN n_table, const CHAR8 **sections, @@ -159,7 +160,7 @@ static VOID locate_sections( } EFI_STATUS pe_alignment_info( - const VOID *base, + const void *base, UINT32 *ret_entry_point_address, UINT32 *ret_size_of_image, UINT32 *ret_section_alignment) { @@ -241,23 +242,23 @@ EFI_STATUS pe_file_locate_sections( assert(offsets); assert(sizes); - err = uefi_call_wrapper(dir->Open, 5, dir, &handle, (CHAR16*)path, EFI_FILE_MODE_READ, 0ULL); + err = dir->Open(dir, &handle, (CHAR16*)path, EFI_FILE_MODE_READ, 0ULL); if (EFI_ERROR(err)) return err; len = sizeof(dos); - err = uefi_call_wrapper(handle->Read, 3, handle, &len, &dos); + err = handle->Read(handle, &len, &dos); if (EFI_ERROR(err)) return err; if (len != sizeof(dos) || !verify_dos(&dos)) return EFI_LOAD_ERROR; - err = uefi_call_wrapper(handle->SetPosition, 2, handle, dos.ExeHeader); + err = handle->SetPosition(handle, dos.ExeHeader); if (EFI_ERROR(err)) return err; len = sizeof(pe); - err = uefi_call_wrapper(handle->Read, 3, handle, &len, &pe); + err = handle->Read(handle, &len, &pe); if (EFI_ERROR(err)) return err; if (len != sizeof(pe) || !verify_pe(&pe)) @@ -268,12 +269,12 @@ EFI_STATUS pe_file_locate_sections( if (!section_table) return EFI_OUT_OF_RESOURCES; - err = uefi_call_wrapper(handle->SetPosition, 2, handle, section_table_offset(&dos, &pe)); + err = handle->SetPosition(handle, section_table_offset(&dos, &pe)); if (EFI_ERROR(err)) return err; len = section_table_len; - err = uefi_call_wrapper(handle->Read, 3, handle, &len, section_table); + err = handle->Read(handle, &len, section_table); if (EFI_ERROR(err)) return err; if (len != section_table_len) diff --git a/src/boot/efi/pe.h b/src/boot/efi/pe.h index 438cfe1b61..3faa5f8730 100644 --- a/src/boot/efi/pe.h +++ b/src/boot/efi/pe.h @@ -17,7 +17,7 @@ EFI_STATUS pe_file_locate_sections( UINTN *sizes); EFI_STATUS pe_alignment_info( - const VOID *base, + const void *base, UINT32 *ret_entry_point_address, UINT32 *ret_size_of_image, UINT32 *ret_section_alignment); diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c index 1505b9d93b..e829cf98b1 100644 --- a/src/boot/efi/random-seed.c +++ b/src/boot/efi/random-seed.c @@ -17,8 +17,8 @@ /* SHA256 gives us 256/8=32 bytes */ #define HASH_VALUE_SIZE 32 -static EFI_STATUS acquire_rng(UINTN size, VOID **ret) { - _cleanup_freepool_ VOID *data = NULL; +static EFI_STATUS acquire_rng(UINTN size, void **ret) { + _cleanup_freepool_ void *data = NULL; EFI_RNG_PROTOCOL *rng; EFI_STATUS err; @@ -26,7 +26,7 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) { /* Try to acquire the specified number of bytes from the UEFI RNG */ - err = LibLocateProtocol((EFI_GUID*) EFI_RNG_GUID, (VOID**) &rng); + err = LibLocateProtocol((EFI_GUID*) EFI_RNG_GUID, (void**) &rng); if (EFI_ERROR(err)) return err; if (!rng) @@ -36,7 +36,7 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) { if (!data) return log_oom(); - err = uefi_call_wrapper(rng->GetRNG, 3, rng, NULL, size, data); + err = rng->GetRNG(rng, NULL, size, data); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to acquire RNG data: %r", err); @@ -44,11 +44,11 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) { return EFI_SUCCESS; } -static VOID hash_once( - const VOID *old_seed, - const VOID *rng, +static void hash_once( + const void *old_seed, + const void *rng, UINTN size, - const VOID *system_token, + const void *system_token, UINTN system_token_size, UINTN counter, UINT8 ret[static HASH_VALUE_SIZE]) { @@ -80,16 +80,16 @@ static VOID hash_once( } static EFI_STATUS hash_many( - const VOID *old_seed, - const VOID *rng, + const void *old_seed, + const void *rng, UINTN size, - const VOID *system_token, + const void *system_token, UINTN system_token_size, UINTN counter_start, UINTN n, - VOID **ret) { + void **ret) { - _cleanup_freepool_ VOID *output = NULL; + _cleanup_freepool_ void *output = NULL; assert(old_seed); assert(rng); @@ -114,15 +114,15 @@ static EFI_STATUS hash_many( } static EFI_STATUS mangle_random_seed( - const VOID *old_seed, - const VOID *rng, + const void *old_seed, + const void *rng, UINTN size, - const VOID *system_token, + const void *system_token, UINTN system_token_size, - VOID **ret_new_seed, - VOID **ret_for_kernel) { + void **ret_new_seed, + void **ret_for_kernel) { - _cleanup_freepool_ VOID *new_seed = NULL, *for_kernel = NULL; + _cleanup_freepool_ void *new_seed = NULL, *for_kernel = NULL; EFI_STATUS err; UINTN n; @@ -156,7 +156,7 @@ static EFI_STATUS mangle_random_seed( return EFI_SUCCESS; } -static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) { +static EFI_STATUS acquire_system_token(void **ret, UINTN *ret_size) { _cleanup_freepool_ CHAR8 *data = NULL; EFI_STATUS err; UINTN size; @@ -180,7 +180,7 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) { return EFI_SUCCESS; } -static VOID validate_sha256(void) { +static void validate_sha256(void) { #ifdef EFI_DEBUG /* Let's validate our SHA256 implementation. We stole it from glibc, and converted it to UEFI @@ -231,7 +231,7 @@ static VOID validate_sha256(void) { } EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { - _cleanup_freepool_ VOID *seed = NULL, *new_seed = NULL, *rng = NULL, *for_kernel = NULL, *system_token = NULL; + _cleanup_freepool_ void *seed = NULL, *new_seed = NULL, *rng = NULL, *for_kernel = NULL, *system_token = NULL; _cleanup_(FileHandleClosep) EFI_FILE_HANDLE handle = NULL; UINTN size, rsize, wsize, system_token_size = 0; _cleanup_freepool_ EFI_FILE_INFO *info = NULL; @@ -256,7 +256,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { if (mode != RANDOM_SEED_ALWAYS && EFI_ERROR(err)) return err; - err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL); + err = root_dir->Open(root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL); if (EFI_ERROR(err)) { if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED) log_error_stall(L"Failed to open random seed file: %r", err); @@ -279,20 +279,20 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { return log_oom(); rsize = size; - err = uefi_call_wrapper(handle->Read, 3, handle, &rsize, seed); + err = handle->Read(handle, &rsize, seed); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to read random seed file: %r", err); if (rsize != size) return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short read on random seed file."); - err = uefi_call_wrapper(handle->SetPosition, 2, handle, 0); + err = handle->SetPosition(handle, 0); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to seek to beginning of random seed file: %r", err); /* Request some random data from the UEFI RNG. We don't need this to work safely, but it's a good * idea to use it because it helps us for cases where users mistakenly include a random seed in * golden master images that are replicated many times. */ - (VOID) acquire_rng(size, &rng); /* It's fine if this fails */ + (void) acquire_rng(size, &rng); /* It's fine if this fails */ /* Calculate new random seed for the disk and what to pass to the kernel */ err = mangle_random_seed(seed, rng, size, system_token, system_token_size, &new_seed, &for_kernel); @@ -301,13 +301,13 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { /* Update the random seed on disk before we use it */ wsize = size; - err = uefi_call_wrapper(handle->Write, 3, handle, &wsize, new_seed); + err = handle->Write(handle, &wsize, new_seed); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to write random seed file: %r", err); if (wsize != size) return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short write on random seed file."); - err = uefi_call_wrapper(handle->Flush, 1, handle); + err = handle->Flush(handle); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Failed to flush random seed file: %r", err); diff --git a/src/boot/efi/random-seed.h b/src/boot/efi/random-seed.h index f14da800ea..e0e055ab03 100644 --- a/src/boot/efi/random-seed.h +++ b/src/boot/efi/random-seed.h @@ -12,4 +12,10 @@ typedef enum RandomSeedMode { _RANDOM_SEED_MODE_INVALID = -EINVAL, } RandomSeedMode; +static const CHAR16 * const random_seed_modes_table[_RANDOM_SEED_MODE_MAX] = { + [RANDOM_SEED_OFF] = L"off", + [RANDOM_SEED_WITH_SYSTEM_TOKEN] = L"with-system-token", + [RANDOM_SEED_ALWAYS] = L"always", +}; + EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode); diff --git a/src/boot/efi/shim.c b/src/boot/efi/shim.c index 9fcc45403e..3ce6af42f9 100644 --- a/src/boot/efi/shim.c +++ b/src/boot/efi/shim.c @@ -22,38 +22,37 @@ #endif struct ShimLock { - EFI_STATUS __sysv_abi__ (*shim_verify) (VOID *buffer, UINT32 size); + EFI_STATUS __sysv_abi__ (*shim_verify) (void *buffer, UINT32 size); /* context is actually a struct for the PE header, but it isn't needed so void is sufficient just do define the interface * see shim.c/shim.h and PeHeader.h in the github shim repo */ - EFI_STATUS __sysv_abi__ (*generate_hash) (VOID *data, UINT32 datasize, VOID *context, UINT8 *sha256hash, UINT8 *sha1hash); + EFI_STATUS __sysv_abi__ (*generate_hash) (void *data, UINT32 datasize, void *context, UINT8 *sha256hash, UINT8 *sha1hash); - EFI_STATUS __sysv_abi__ (*read_header) (VOID *data, UINT32 datasize, VOID *context); + EFI_STATUS __sysv_abi__ (*read_header) (void *data, UINT32 datasize, void *context); }; -#define SIMPLE_FS_GUID &(const EFI_GUID) SIMPLE_FILE_SYSTEM_PROTOCOL #define SHIM_LOCK_GUID \ &(const EFI_GUID) { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } } BOOLEAN shim_loaded(void) { struct ShimLock *shim_lock; - return uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) SHIM_LOCK_GUID, NULL, (VOID**) &shim_lock) == EFI_SUCCESS; + return !EFI_ERROR(BS->LocateProtocol((EFI_GUID*) SHIM_LOCK_GUID, NULL, (void**) &shim_lock)); } -static BOOLEAN shim_validate(VOID *data, UINT32 size) { +static BOOLEAN shim_validate(void *data, UINT32 size) { struct ShimLock *shim_lock; if (!data) return FALSE; - if (uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) SHIM_LOCK_GUID, NULL, (VOID**) &shim_lock) != EFI_SUCCESS) + if (EFI_ERROR(BS->LocateProtocol((EFI_GUID*) SHIM_LOCK_GUID, NULL, (void**) &shim_lock))) return FALSE; if (!shim_lock) return FALSE; - return shim_lock->shim_verify(data, size) == EFI_SUCCESS; + return !EFI_ERROR(shim_lock->shim_verify(data, size)); } /* Handle to the original authenticator for security1 protocol */ @@ -72,14 +71,14 @@ static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL; */ static EFIAPI EFI_STATUS security2_policy_authentication (const EFI_SECURITY2_PROTOCOL *this, const EFI_DEVICE_PATH_PROTOCOL *device_path, - VOID *file_buffer, UINTN file_size, BOOLEAN boot_policy) { + void *file_buffer, UINTN file_size, BOOLEAN boot_policy) { EFI_STATUS status; assert(this); /* device_path and file_buffer may be NULL */ /* Chain original security policy */ - status = uefi_call_wrapper(es2fa, 5, this, device_path, file_buffer, file_size, boot_policy); + status = es2fa(this, device_path, file_buffer, file_size, boot_policy); /* if OK, don't bother with MOK check */ if (!EFI_ERROR(status)) @@ -111,31 +110,34 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT UINTN file_size; assert(this); - assert(device_path_const); if (!device_path_const) return EFI_INVALID_PARAMETER; dev_path = DuplicateDevicePath((EFI_DEVICE_PATH*) device_path_const); + if (!dev_path) + return EFI_OUT_OF_RESOURCES; - status = uefi_call_wrapper(BS->LocateDevicePath, 3, (EFI_GUID*) SIMPLE_FS_GUID, &dev_path, &h); - if (status != EFI_SUCCESS) + status = BS->LocateDevicePath(&FileSystemProtocol, &dev_path, &h); + if (EFI_ERROR(status)) return status; /* No need to check return value, this already happened in efi_main() */ root = LibOpenRoot(h); dev_path_str = DevicePathToStr(dev_path); + if (!dev_path_str) + return EFI_OUT_OF_RESOURCES; status = file_read(root, dev_path_str, 0, 0, &file_buffer, &file_size); if (EFI_ERROR(status)) return status; - uefi_call_wrapper(root->Close, 1, root); + root->Close(root); if (shim_validate(file_buffer, file_size)) return EFI_SUCCESS; /* Try using the platform's native policy.... */ - return uefi_call_wrapper(esfas, 3, this, authentication_status, device_path_const); + return esfas(this, authentication_status, device_path_const); } EFI_STATUS security_policy_install(void) { @@ -152,11 +154,11 @@ EFI_STATUS security_policy_install(void) { * to fail, since SECURITY2 was introduced in PI 1.2.1. * Use security2_protocol == NULL as indicator. */ - uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) SECURITY_PROTOCOL2_GUID, NULL, (VOID**) &security2_protocol); + BS->LocateProtocol((EFI_GUID*) SECURITY_PROTOCOL2_GUID, NULL, (void**) &security2_protocol); - status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) SECURITY_PROTOCOL_GUID, NULL, (VOID**) &security_protocol); + status = BS->LocateProtocol((EFI_GUID*) SECURITY_PROTOCOL_GUID, NULL, (void**) &security_protocol); /* This one is mandatory, so there's a serious problem */ - if (status != EFI_SUCCESS) + if (EFI_ERROR(status)) return status; esfas = security_protocol->FileAuthenticationState; diff --git a/src/boot/efi/splash.c b/src/boot/efi/splash.c index 0071a9317b..fa923e77f2 100644 --- a/src/boot/efi/splash.c +++ b/src/boot/efi/splash.c @@ -135,7 +135,7 @@ static EFI_STATUS bmp_parse_header( return EFI_SUCCESS; } -static VOID pixel_blend(UINT32 *dst, const UINT32 source) { +static void pixel_blend(UINT32 *dst, const UINT32 source) { UINT32 alpha, src, src_rb, src_g, dst_rb, dst_g, rb, g; assert(dst); @@ -256,13 +256,12 @@ static EFI_STATUS bmp_to_blt( EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *background) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL pixel = {}; - static const EFI_GUID GraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL; struct bmp_dib *dib; struct bmp_map *map; const UINT8 *pixmap; UINT64 blt_size; - _cleanup_freepool_ VOID *blt = NULL; + _cleanup_freepool_ void *blt = NULL; UINTN x_pos = 0; UINTN y_pos = 0; EFI_STATUS err; @@ -281,7 +280,7 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O background = &pixel; } - err = LibLocateProtocol((EFI_GUID*) &GraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput); + err = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&GraphicsOutput); if (EFI_ERROR(err)) return err; @@ -294,11 +293,13 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O if (dib->y < GraphicsOutput->Mode->Info->VerticalResolution) y_pos = (GraphicsOutput->Mode->Info->VerticalResolution - dib->y) / 2; - uefi_call_wrapper(GraphicsOutput->Blt, 10, GraphicsOutput, - (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)background, - EfiBltVideoFill, 0, 0, 0, 0, - GraphicsOutput->Mode->Info->HorizontalResolution, - GraphicsOutput->Mode->Info->VerticalResolution, 0); + err = GraphicsOutput->Blt( + GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)background, + EfiBltVideoFill, 0, 0, 0, 0, + GraphicsOutput->Mode->Info->HorizontalResolution, + GraphicsOutput->Mode->Info->VerticalResolution, 0); + if (EFI_ERROR(err)) + return err; /* EFI buffer */ blt_size = sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * dib->x * dib->y; @@ -306,9 +307,10 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O if (!blt) return EFI_OUT_OF_RESOURCES; - err = uefi_call_wrapper(GraphicsOutput->Blt, 10, GraphicsOutput, - blt, EfiBltVideoToBltBuffer, x_pos, y_pos, 0, 0, - dib->x, dib->y, 0); + err = GraphicsOutput->Blt( + GraphicsOutput, blt, + EfiBltVideoToBltBuffer, x_pos, y_pos, 0, 0, + dib->x, dib->y, 0); if (EFI_ERROR(err)) return err; @@ -320,7 +322,8 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O if (EFI_ERROR(err)) return err; - return uefi_call_wrapper(GraphicsOutput->Blt, 10, GraphicsOutput, - blt, EfiBltBufferToVideo, 0, 0, x_pos, y_pos, - dib->x, dib->y, 0); + return GraphicsOutput->Blt( + GraphicsOutput, blt, + EfiBltBufferToVideo, 0, 0, x_pos, y_pos, + dib->x, dib->y, 0); } diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 01774d1fd5..256aa21827 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -19,8 +19,8 @@ _used_ _section_(".sdmagic") static const char magic[] = "#### LoaderInfo: syste static EFI_STATUS combine_initrd( EFI_PHYSICAL_ADDRESS initrd_base, UINTN initrd_size, - const VOID *credential_initrd, UINTN credential_initrd_size, - const VOID *sysext_initrd, UINTN sysext_initrd_size, + const void *credential_initrd, UINTN credential_initrd_size, + const void *sysext_initrd, UINTN sysext_initrd_size, EFI_PHYSICAL_ADDRESS *ret_initrd_base, UINTN *ret_initrd_size) { EFI_PHYSICAL_ADDRESS base = UINT32_MAX; /* allocate an area below the 32bit boundary for this */ @@ -47,8 +47,7 @@ static EFI_STATUS combine_initrd( n += sysext_initrd_size; } - err = uefi_call_wrapper( - BS->AllocatePages, 4, + err = BS->AllocatePages( AllocateMaxAddress, EfiLoaderData, EFI_SIZE_TO_PAGES(n), @@ -90,7 +89,7 @@ static EFI_STATUS combine_initrd( return EFI_SUCCESS; } -static VOID export_variables(EFI_LOADED_IMAGE *loaded_image) { +static void export_variables(EFI_LOADED_IMAGE *loaded_image) { CHAR16 uuid[37]; assert(loaded_image); @@ -111,7 +110,10 @@ static VOID export_variables(EFI_LOADED_IMAGE *loaded_image) { _cleanup_freepool_ CHAR16 *s = NULL; s = DevicePathToStr(loaded_image->FilePath); - efivar_set(LOADER_GUID, L"LoaderImageIdentifier", s, 0); + if (s) + efivar_set(LOADER_GUID, L"LoaderImageIdentifier", s, 0); + else + log_oom(); } /* if LoaderFirmwareInfo is not set, let's set it */ @@ -119,7 +121,10 @@ static VOID export_variables(EFI_LOADED_IMAGE *loaded_image) { _cleanup_freepool_ CHAR16 *s = NULL; s = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); - efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", s, 0); + if (s) + efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", s, 0); + else + log_oom(); } /* ditto for LoaderFirmwareType */ @@ -127,7 +132,10 @@ static VOID export_variables(EFI_LOADED_IMAGE *loaded_image) { _cleanup_freepool_ CHAR16 *s = NULL; s = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); - efivar_set(LOADER_GUID, L"LoaderFirmwareType", s, 0); + if (s) + efivar_set(LOADER_GUID, L"LoaderFirmwareType", s, 0); + else + log_oom(); } /* add StubInfo */ @@ -157,7 +165,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { UINTN cmdline_len = 0, linux_size, initrd_size, dt_size; UINTN credential_initrd_size = 0, sysext_initrd_size = 0; - _cleanup_freepool_ VOID *credential_initrd = NULL, *sysext_initrd = NULL; + _cleanup_freepool_ void *credential_initrd = NULL, *sysext_initrd = NULL; EFI_PHYSICAL_ADDRESS linux_base, initrd_base, dt_base; _cleanup_(devicetree_cleanup) struct devicetree_state dt_state = {}; EFI_LOADED_IMAGE *loaded_image; @@ -168,8 +176,13 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { InitializeLib(image, sys_table); - err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, - image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + err = BS->OpenProtocol( + image, + &LoadedImageProtocol, + (void **)&loaded_image, + image, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(err)) return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err); @@ -194,6 +207,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { options = (CHAR16 *)loaded_image->LoadOptions; cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8); line = AllocatePool(cmdline_len); + if (!line) + return log_oom(); + for (UINTN i = 0; i < cmdline_len; i++) line[i] = options[i]; cmdline = line; @@ -202,12 +218,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { * duplicates what we already did in the boot menu, if that was already used. However, since * we want the boot menu to support an EFI binary, and want to this stub to be usable from * any boot menu, let's measure things anyway. */ - (VOID) tpm_log_load_options(loaded_image->LoadOptions); + (void) tpm_log_load_options(loaded_image->LoadOptions); } export_variables(loaded_image); - (VOID) pack_cpio(loaded_image, + (void) pack_cpio(loaded_image, L".cred", (const CHAR8*) ".extra/credentials", /* dir_mode= */ 0500, @@ -217,7 +233,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { &credential_initrd, &credential_initrd_size); - (VOID) pack_cpio(loaded_image, + (void) pack_cpio(loaded_image, L".raw", (const CHAR8*) ".extra/sysext", /* dir_mode= */ 0555, diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 13697c9433..9128c507c8 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -6,50 +6,50 @@ #include "util.h" #ifdef __x86_64__ -UINT64 ticks_read(VOID) { +UINT64 ticks_read(void) { UINT64 a, d; __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); return (d << 32) | a; } #elif defined(__i386__) -UINT64 ticks_read(VOID) { +UINT64 ticks_read(void) { UINT64 val; __asm__ volatile ("rdtsc" : "=A" (val)); return val; } #elif defined(__aarch64__) -UINT64 ticks_read(VOID) { +UINT64 ticks_read(void) { UINT64 val; __asm__ volatile ("mrs %0, cntpct_el0" : "=r" (val)); return val; } #else -UINT64 ticks_read(VOID) { +UINT64 ticks_read(void) { UINT64 val = 1; return val; } #endif #if defined(__aarch64__) -UINT64 ticks_freq(VOID) { +UINT64 ticks_freq(void) { UINT64 freq; __asm__ volatile ("mrs %0, cntfrq_el0": "=r" (freq)); return freq; } #else /* count TSC ticks during a millisecond delay */ -UINT64 ticks_freq(VOID) { +UINT64 ticks_freq(void) { UINT64 ticks_start, ticks_end; ticks_start = ticks_read(); - uefi_call_wrapper(BS->Stall, 1, 1000); + BS->Stall(1000); ticks_end = ticks_read(); return (ticks_end - ticks_start) * 1000UL; } #endif -UINT64 time_usec(VOID) { +UINT64 time_usec(void) { UINT64 ticks; static UINT64 freq; @@ -95,13 +95,13 @@ EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b) { return EFI_INVALID_PARAMETER; } -EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, UINT32 flags) { +EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const void *buf, UINTN size, UINT32 flags) { assert(vendor); assert(name); assert(buf || size == 0); flags |= EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; - return uefi_call_wrapper(RT->SetVariable, 5, (CHAR16*) name, (EFI_GUID *) vendor, flags, size, (VOID*) buf); + return RT->SetVariable((CHAR16 *) name, (EFI_GUID *) vendor, flags, size, (void *) buf); } EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, UINT32 flags) { @@ -260,7 +260,7 @@ EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **bu if (!buf) return EFI_OUT_OF_RESOURCES; - err = uefi_call_wrapper(RT->GetVariable, 5, (CHAR16*) name, (EFI_GUID *)vendor, NULL, &l, buf); + err = RT->GetVariable((CHAR16 *) name, (EFI_GUID *) vendor, NULL, &l, buf); if (!EFI_ERROR(err)) { if (buffer) @@ -289,7 +289,7 @@ EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOO return err; } -VOID efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 usec) { +void efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 usec) { CHAR16 str[32]; assert(vendor); @@ -368,6 +368,8 @@ CHAR16 *stra_to_str(const CHAR8 *stra) { len = strlena(stra); str = AllocatePool((len + 1) * sizeof(CHAR16)); + if (!str) + return NULL; strlen = 0; i = 0; @@ -398,6 +400,8 @@ CHAR16 *stra_to_path(const CHAR8 *stra) { len = strlena(stra); str = AllocatePool((len + 2) * sizeof(CHAR16)); + if (!str) + return NULL; str[0] = '\\'; strlen = 1; @@ -447,7 +451,7 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s assert(name); assert(ret); - err = uefi_call_wrapper(dir->Open, 5, dir, &handle, (CHAR16*) name, EFI_FILE_MODE_READ, 0ULL); + err = dir->Open(dir, &handle, (CHAR16*) name, EFI_FILE_MODE_READ, 0ULL); if (EFI_ERROR(err)) return err; @@ -462,7 +466,7 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s } if (off > 0) { - err = uefi_call_wrapper(handle->SetPosition, 2, handle, off); + err = handle->SetPosition(handle, off); if (EFI_ERROR(err)) return err; } @@ -471,7 +475,7 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s if (!buf) return EFI_OUT_OF_RESOURCES; - err = uefi_call_wrapper(handle->Read, 3, handle, &size, buf); + err = handle->Read(handle, &size, buf); if (EFI_ERROR(err)) return err; @@ -484,12 +488,12 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s return err; } -VOID log_error_stall(const CHAR16 *fmt, ...) { +void log_error_stall(const CHAR16 *fmt, ...) { va_list args; assert(fmt); - uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK); + ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK); Print(L"\n"); va_start(args, fmt); @@ -497,7 +501,7 @@ VOID log_error_stall(const CHAR16 *fmt, ...) { va_end(args); Print(L"\n"); - uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); + BS->Stall(3 * 1000 * 1000); } EFI_STATUS log_oom(void) { @@ -505,34 +509,34 @@ EFI_STATUS log_oom(void) { return EFI_OUT_OF_RESOURCES; } -VOID *memmem_safe(const VOID *haystack, UINTN haystack_len, const VOID *needle, UINTN needle_len) { +void *memmem_safe(const void *haystack, UINTN haystack_len, const void *needle, UINTN needle_len) { assert(haystack || haystack_len == 0); assert(needle || needle_len == 0); if (needle_len == 0) - return (VOID*)haystack; + return (void*)haystack; for (const CHAR8 *h = haystack, *n = needle; haystack_len >= needle_len; h++, haystack_len--) if (*h == *n && CompareMem(h + 1, n + 1, needle_len - 1) == 0) - return (VOID*)h; + return (void*)h; return NULL; } -VOID print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str) { +void print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str) { assert(str); - uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, x, y); - uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, attr); - uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, (CHAR16*)str); + ST->ConOut->SetCursorPosition(ST->ConOut, x, y); + ST->ConOut->SetAttribute(ST->ConOut, attr); + ST->ConOut->OutputString(ST->ConOut, (CHAR16*)str); } -VOID clear_screen(UINTN attr) { - uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, attr); - uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); +void clear_screen(UINTN attr) { + ST->ConOut->SetAttribute(ST->ConOut, attr); + ST->ConOut->ClearScreen(ST->ConOut); } void sort_pointer_array( - VOID **array, + void **array, UINTN n_members, compare_pointer_func_t compare) { @@ -566,7 +570,6 @@ EFI_STATUS get_file_info_harder( EFI_FILE_INFO **ret, UINTN *ret_size) { - static const EFI_GUID EfiFileInfoGuid = EFI_FILE_INFO_ID; UINTN size = OFFSETOF(EFI_FILE_INFO, FileName) + 256; _cleanup_freepool_ EFI_FILE_INFO *fi = NULL; EFI_STATUS err; @@ -580,14 +583,14 @@ EFI_STATUS get_file_info_harder( if (!fi) return EFI_OUT_OF_RESOURCES; - err = uefi_call_wrapper(handle->GetInfo, 4, handle, (EFI_GUID*) &EfiFileInfoGuid, &size, fi); + err = handle->GetInfo(handle, &GenericFileInfo, &size, fi); if (err == EFI_BUFFER_TOO_SMALL) { FreePool(fi); fi = AllocatePool(size); /* GetInfo tells us the required size, let's use that now */ if (!fi) return EFI_OUT_OF_RESOURCES; - err = uefi_call_wrapper(handle->GetInfo, 4, handle, (EFI_GUID*) &EfiFileInfoGuid, &size, fi); + err = handle->GetInfo(handle, &GenericFileInfo, &size, fi); } if (EFI_ERROR(err)) @@ -627,7 +630,7 @@ EFI_STATUS readdir_harder( } else sz = *buffer_size; - err = uefi_call_wrapper(handle->Read, 3, handle, &sz, *buffer); + err = handle->Read(handle, &sz, *buffer); if (err == EFI_BUFFER_TOO_SMALL) { FreePool(*buffer); @@ -639,7 +642,7 @@ EFI_STATUS readdir_harder( *buffer_size = sz; - err = uefi_call_wrapper(handle->Read, 3, handle, &sz, *buffer); + err = handle->Read(handle, &sz, *buffer); } if (EFI_ERROR(err)) return err; @@ -724,13 +727,7 @@ EFI_STATUS open_directory( /* Opens a file, and then verifies it is actually a directory */ - err = uefi_call_wrapper( - root->Open, 5, - root, - &dir, - (CHAR16*) path, - EFI_FILE_MODE_READ, - 0ULL); + err = root->Open(root, &dir, (CHAR16*) path, EFI_FILE_MODE_READ, 0ULL); if (EFI_ERROR(err)) return err; @@ -744,7 +741,7 @@ EFI_STATUS open_directory( return EFI_SUCCESS; } -UINT64 get_os_indications_supported(VOID) { +UINT64 get_os_indications_supported(void) { UINT64 osind; EFI_STATUS err; diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index fa17b18f42..e925f1728b 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -24,13 +24,6 @@ #define UINT64_MAX ((UINT64) -1) #endif -static inline UINTN ALIGN_TO(UINTN l, UINTN ali) { - if (l > UINTN_MAX - (ali - 1)) /* Overflow? */ - return UINTN_MAX; - - return ((l + (ali - 1)) & ~(ali - 1)); -} - EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b); UINT64 ticks_read(void); @@ -38,11 +31,11 @@ UINT64 ticks_freq(void); UINT64 time_usec(void); EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, UINT32 flags); -EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, UINT32 flags); +EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const void *buf, UINTN size, UINT32 flags); EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN i, UINT32 flags); EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const CHAR16 *NAME, UINT32 value, UINT32 flags); EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 value, UINT32 flags); -VOID efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 usec); +void efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 usec); EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value); EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size); @@ -72,7 +65,7 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) { if (!*handle) return; - uefi_call_wrapper((*handle)->Close, 1, *handle); + (*handle)->Close(*handle); } /* @@ -84,7 +77,7 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) { &(const EFI_GUID) { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } } #define EFI_GLOBAL_GUID &(const EFI_GUID) EFI_GLOBAL_VARIABLE -VOID log_error_stall(const CHAR16 *fmt, ...); +void log_error_stall(const CHAR16 *fmt, ...); EFI_STATUS log_oom(void); /* This works just like log_error_errno() from userspace, but requires you @@ -95,18 +88,18 @@ EFI_STATUS log_oom(void); err; \ }) -VOID *memmem_safe(const VOID *haystack, UINTN haystack_len, const VOID *needle, UINTN needle_len); +void *memmem_safe(const void *haystack, UINTN haystack_len, const void *needle, UINTN needle_len); -static inline VOID *mempmem_safe(const VOID *haystack, UINTN haystack_len, const VOID *needle, UINTN needle_len) { +static inline void *mempmem_safe(const void *haystack, UINTN haystack_len, const void *needle, UINTN needle_len) { CHAR8 *p = memmem_safe(haystack, haystack_len, needle, needle_len); return p ? p + needle_len : NULL; } -VOID print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str); -VOID clear_screen(UINTN attr); +void print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str); +void clear_screen(UINTN attr); -typedef INTN (*compare_pointer_func_t)(const VOID *a, const VOID *b); -void sort_pointer_array(VOID **array, UINTN n_members, compare_pointer_func_t compare); +typedef INTN (*compare_pointer_func_t)(const void *a, const void *b); +void sort_pointer_array(void **array, UINTN n_members, compare_pointer_func_t compare); EFI_STATUS get_file_info_harder(EFI_FILE_HANDLE handle, EFI_FILE_INFO **ret, UINTN *ret_size); @@ -145,4 +138,4 @@ static inline void *PHYSICAL_ADDRESS_TO_POINTER(EFI_PHYSICAL_ADDRESS addr) { return (void*) (UINTN) addr; } -UINT64 get_os_indications_supported(VOID); +UINT64 get_os_indications_supported(void); diff --git a/src/boot/efi/xbootldr.c b/src/boot/efi/xbootldr.c index ef7ca6cf4f..39c3c99d6e 100644 --- a/src/boot/efi/xbootldr.c +++ b/src/boot/efi/xbootldr.c @@ -9,7 +9,7 @@ union GptHeaderBuffer { EFI_PARTITION_TABLE_HEADER gpt_header; - uint8_t space[((sizeof(EFI_PARTITION_TABLE_HEADER) + 511) / 512) * 512]; + uint8_t space[CONST_ALIGN_TO(sizeof(EFI_PARTITION_TABLE_HEADER), 512)]; }; static EFI_DEVICE_PATH *path_parent(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node) { @@ -95,8 +95,7 @@ static EFI_STATUS try_gpt( assert(ret_part_uuid); /* Read the GPT header */ - err = uefi_call_wrapper( - block_io->ReadBlocks, 5, + err = block_io->ReadBlocks( block_io, block_io->Media->MediaId, lba, @@ -117,8 +116,7 @@ static EFI_STATUS try_gpt( if (!entries) return EFI_OUT_OF_RESOURCES; - err = uefi_call_wrapper( - block_io->ReadBlocks, 5, + err = block_io->ReadBlocks( block_io, block_io->Media->MediaId, gpt.gpt_header.PartitionEntryLBA, @@ -199,11 +197,11 @@ static EFI_STATUS find_device( if (!disk_path) continue; - err = uefi_call_wrapper(BS->LocateDevicePath, 3, &BlockIoProtocol, &p, &disk_handle); + err = BS->LocateDevicePath(&BlockIoProtocol, &p, &disk_handle); if (EFI_ERROR(err)) continue; - err = uefi_call_wrapper(BS->HandleProtocol, 3, disk_handle, &BlockIoProtocol, (VOID **)&block_io); + err = BS->HandleProtocol(disk_handle, &BlockIoProtocol, (void **)&block_io); if (EFI_ERROR(err)) continue; @@ -292,7 +290,7 @@ EFI_STATUS xbootldr_open(EFI_HANDLE *device, EFI_HANDLE *ret_device, EFI_FILE ** hd->SignatureType = SIGNATURE_TYPE_GUID; } - err = uefi_call_wrapper(BS->LocateDevicePath, 3, &BlockIoProtocol, &partition_path, &new_device); + err = BS->LocateDevicePath(&BlockIoProtocol, &partition_path, &new_device); if (EFI_ERROR(err)) return err; diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h index 940b661b0e..36d759ea1d 100644 --- a/src/fundamental/macro-fundamental.h +++ b/src/fundamental/macro-fundamental.h @@ -5,6 +5,7 @@ #include #endif +#include #include "type.h" #define _align_(x) __attribute__((__aligned__(x))) @@ -273,3 +274,34 @@ free(memory); \ (typeof(memory)) NULL; \ }) + +static inline size_t ALIGN_TO(size_t l, size_t ali) { + /* sd-boot uses UINTN for size_t, let's make sure SIZE_MAX is correct. */ + assert_cc(SIZE_MAX == ~(size_t)0); + + /* Check that alignment is exponent of 2 */ +#if SIZE_MAX == UINT_MAX + assert(__builtin_popcount(ali) == 1); +#elif SIZE_MAX == ULONG_MAX + assert(__builtin_popcountl(ali) == 1); +#elif SIZE_MAX == ULLONG_MAX + assert(__builtin_popcountll(ali) == 1); +#else + #error "Unexpected size_t" +#endif + + if (l > SIZE_MAX - (ali - 1)) + return SIZE_MAX; /* indicate overflow */ + + return ((l + ali - 1) & ~(ali - 1)); +} + +/* Same as ALIGN_TO but callable in constant contexts. */ +#define CONST_ALIGN_TO(l, ali) \ + __builtin_choose_expr( \ + __builtin_constant_p(l) && \ + __builtin_constant_p(ali) && \ + __builtin_popcountll(ali) == 1 && /* is power of 2? */ \ + (l <= SIZE_MAX - (ali - 1)), /* overflow? */ \ + ((l) + (ali) - 1) & ~((ali) - 1), \ + VOID_0) diff --git a/src/libsystemd/sd-journal/catalog.c b/src/libsystemd/sd-journal/catalog.c index ce8d47ccc3..4a2ba02ad0 100644 --- a/src/libsystemd/sd-journal/catalog.c +++ b/src/libsystemd/sd-journal/catalog.c @@ -395,7 +395,7 @@ static int64_t write_catalog( header = (CatalogHeader) { .signature = CATALOG_SIGNATURE, - .header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8)), + .header_size = htole64(CONST_ALIGN_TO(sizeof(CatalogHeader), 8)), .catalog_item_size = htole64(sizeof(CatalogItem)), .n_items = htole64(n), }; diff --git a/src/test/test-macro.c b/src/test/test-macro.c index 4acbbfb7af..495221c1d5 100644 --- a/src/test/test-macro.c +++ b/src/test/test-macro.c @@ -325,6 +325,15 @@ static void test_align_to(void) { assert_se(ALIGN_TO(SIZE_MAX-2, 4) == SIZE_MAX); /* overflow */ assert_se(ALIGN_TO(SIZE_MAX-1, 4) == SIZE_MAX); /* overflow */ assert_se(ALIGN_TO(SIZE_MAX, 4) == SIZE_MAX); /* overflow */ + + assert_cc(CONST_ALIGN_TO(96, 512) == 512); + assert_cc(CONST_ALIGN_TO(511, 512) == 512); + assert_cc(CONST_ALIGN_TO(512, 512) == 512); + assert_cc(CONST_ALIGN_TO(513, 512) == 1024); + assert_cc(CONST_ALIGN_TO(sizeof(int), 64) == 64); + + assert_cc(__builtin_types_compatible_p(typeof(CONST_ALIGN_TO(4, 3)), void)); + assert_cc(__builtin_types_compatible_p(typeof(CONST_ALIGN_TO(SIZE_MAX, 512)), void)); } int main(int argc, char *argv[]) {