MISRA C Rule 2.1 states: "A project shall not contain unreachable code."
Function `PrintErrMesg(const CHAR16*, EFI_STATUS)` isn't intended to return control to its caller. At the end, it calls `blexit()`, which, in turn, invokes the `__builtin_unreachable()` function, making subsequent return statements in `read_file()` unreachable: PrintErrMesg(name, ret); /* not reached */ return false; This also causes unreachability of the code meant to handle `read_file()` errors, as seen in these examples: In this block: if ( read_file(dir_handle, file_name, &cfg, NULL) ) break; *tail = 0; } if ( !tail ) blexit(L"No configuration file found."); And here: else if ( !read_file(dir_handle, cfg_file_name, &cfg, NULL) ) blexit(L"Configuration file not found."); And here: if ( !read_file(dir_handle, s2w(&name), &cfg, NULL) ) { PrintStr(L"Chained configuration file '"); PrintStr(name.w); efi_bs->FreePool(name.w); blexit(L"'not found."); } The issue arises because when an error occurs inside `read_file()`, it calls `PrintErrMesg()` and does not return to the caller. To address this the following changes are applied: 1. Remove `PrintErrMesg(name, ret);` from the `read_file()` function. 2. Replaced it with `PrintErr(name);`, which prints the file name and returns control to the caller. 3. Change the `read_file()` return type from `bool` to `EFI_STATUS`, allowing file operation result codes to be returned to the caller. 4. Properly handle error codes returned from the `read_file()` function in the relevant areas of the code. 5. Replace `blexit()` calls with informative error codes using `PrintErrMesg()` where appropriate. Signed-off-by: Dmytro Prokopchuk <dmytro_prokopch...@epam.com> --- Test CI pipeline: https://gitlab.com/xen-project/people/dimaprkp4k/xen/-/pipelines/1980590118 --- xen/common/efi/boot.c | 57 ++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c index 50ff1d1bd2..ddbafb2f9c 100644 --- a/xen/common/efi/boot.c +++ b/xen/common/efi/boot.c @@ -132,7 +132,7 @@ struct file { }; }; -static bool read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name, +static EFI_STATUS read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name, struct file *file, const char *options); static bool read_section(const EFI_LOADED_IMAGE *image, const CHAR16 *name, struct file *file, const char *options); @@ -782,7 +782,7 @@ static void __init handle_file_info(const CHAR16 *name, efi_arch_handle_module(file, name, options); } -static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name, +static EFI_STATUS __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name, struct file *file, const char *options) { EFI_FILE_HANDLE FileHandle = NULL; @@ -791,7 +791,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name, const CHAR16 *what = NULL; if ( !name ) - PrintErrMesg(L"No filename", EFI_OUT_OF_RESOURCES); + return EFI_INVALID_PARAMETER; what = L"Open"; if ( dir_handle ) @@ -842,7 +842,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name, efi_arch_flush_dcache_area(file->ptr, file->size); - return true; + return ret; fail: if ( FileHandle ) @@ -850,10 +850,9 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name, PrintErr(what); PrintErr(L" failed for "); - PrintErrMesg(name, ret); + PrintErr(name); - /* not reached */ - return false; + return ret; } static bool __init read_section(const EFI_LOADED_IMAGE *image, @@ -1433,18 +1432,20 @@ void EFIAPI __init noreturn efi_start(EFI_HANDLE ImageHandle, while ( (tail = point_tail(file_name)) != NULL ) { wstrcpy(tail, L".cfg"); - if ( read_file(dir_handle, file_name, &cfg, NULL) ) + if ( (status = read_file(dir_handle, file_name, + &cfg, NULL)) == EFI_SUCCESS ) break; *tail = 0; } if ( !tail ) - blexit(L"No configuration file found."); + PrintErrMesg(L"Configuration file failure.", status); PrintStr(L"Using configuration file '"); PrintStr(file_name); PrintStr(L"'\r\n"); } - else if ( !read_file(dir_handle, cfg_file_name, &cfg, NULL) ) - blexit(L"Configuration file not found."); + else if ( (status = read_file(dir_handle, cfg_file_name, + &cfg, NULL)) != EFI_SUCCESS ) + PrintErrMesg(L"Configuration file failure.", status); pre_parse(&cfg); if ( section.w ) @@ -1465,12 +1466,13 @@ void EFIAPI __init noreturn efi_start(EFI_HANDLE ImageHandle, efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size)); cfg.need_to_free = false; } - if ( !read_file(dir_handle, s2w(&name), &cfg, NULL) ) + if ( (status = read_file(dir_handle, s2w(&name), + &cfg, NULL)) != EFI_SUCCESS ) { - PrintStr(L"Chained configuration file '"); + PrintStr(L"Configuration file '"); PrintStr(name.w); efi_bs->FreePool(name.w); - blexit(L"'not found."); + PrintErrMesg(L"'failure.", status); } pre_parse(&cfg); efi_bs->FreePool(name.w); @@ -1483,7 +1485,14 @@ void EFIAPI __init noreturn efi_start(EFI_HANDLE ImageHandle, if ( !read_section(loaded_image, L"kernel", &kernel, option_str) && name.s ) { - read_file(dir_handle, s2w(&name), &kernel, option_str); + status = read_file(dir_handle, s2w(&name), &kernel, option_str); + if ( status != EFI_SUCCESS ) + { + PrintStr(L"Configuration file '"); + PrintStr(name.w); + efi_bs->FreePool(name.w); + PrintErrMesg(L"'failure.", status); + } efi_bs->FreePool(name.w); } else @@ -1497,7 +1506,14 @@ void EFIAPI __init noreturn efi_start(EFI_HANDLE ImageHandle, name.s = get_value(&cfg, section.s, "ramdisk"); if ( name.s ) { - read_file(dir_handle, s2w(&name), &ramdisk, NULL); + status = read_file(dir_handle, s2w(&name), &ramdisk, NULL); + if ( status != EFI_SUCCESS ) + { + PrintStr(L"Configuration file '"); + PrintStr(name.w); + efi_bs->FreePool(name.w); + PrintErrMesg(L"'failure.", status); + } efi_bs->FreePool(name.w); } } @@ -1507,7 +1523,14 @@ void EFIAPI __init noreturn efi_start(EFI_HANDLE ImageHandle, name.s = get_value(&cfg, section.s, "xsm"); if ( name.s ) { - read_file(dir_handle, s2w(&name), &xsm, NULL); + status = read_file(dir_handle, s2w(&name), &xsm, NULL); + if ( status != EFI_SUCCESS ) + { + PrintStr(L"Configuration file '"); + PrintStr(name.w); + efi_bs->FreePool(name.w); + PrintErrMesg(L"'failure.", status); + } efi_bs->FreePool(name.w); } } -- 2.43.0