From 55944e5e40b1be2afc4855d8d2baf4b73d1876b5 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:49:52 +0200 Subject: Adding upstream version 255.4. Signed-off-by: Daniel Baumann --- src/boot/efi/log.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/boot/efi/log.c (limited to 'src/boot/efi/log.c') diff --git a/src/boot/efi/log.c b/src/boot/efi/log.c new file mode 100644 index 0000000..364471e --- /dev/null +++ b/src/boot/efi/log.c @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "log.h" +#include "proto/rng.h" +#include "proto/simple-text-io.h" +#include "util.h" + +static unsigned log_count = 0; + +void freeze(void) { + for (;;) + BS->Stall(60 * 1000 * 1000); +} + +_noreturn_ static void panic(const char16_t *message) { + if (ST->ConOut->Mode->CursorColumn > 0) + ST->ConOut->OutputString(ST->ConOut, (char16_t *) u"\r\n"); + ST->ConOut->SetAttribute(ST->ConOut, EFI_TEXT_ATTR(EFI_LIGHTRED, EFI_BLACK)); + ST->ConOut->OutputString(ST->ConOut, (char16_t *) message); + freeze(); +} + +void efi_assert(const char *expr, const char *file, unsigned line, const char *function) { + static bool asserting = false; + + /* Let's be paranoid. */ + if (asserting) + panic(u"systemd-boot: Nested assertion failure, halting."); + + asserting = true; + log_error("systemd-boot: Assertion '%s' failed at %s:%u@%s, halting.", expr, file, line, function); + freeze(); +} + +EFI_STATUS log_internal(EFI_STATUS status, const char *format, ...) { + assert(format); + + int32_t attr = ST->ConOut->Mode->Attribute; + + if (ST->ConOut->Mode->CursorColumn > 0) + ST->ConOut->OutputString(ST->ConOut, (char16_t *) u"\r\n"); + ST->ConOut->SetAttribute(ST->ConOut, EFI_TEXT_ATTR(EFI_LIGHTRED, EFI_BLACK)); + + va_list ap; + va_start(ap, format); + vprintf_status(status, format, ap); + va_end(ap); + + ST->ConOut->OutputString(ST->ConOut, (char16_t *) u"\r\n"); + ST->ConOut->SetAttribute(ST->ConOut, attr); + + log_count++; + return status; +} + +#ifdef EFI_DEBUG +void log_hexdump(const char16_t *prefix, const void *data, size_t size) { + /* Debugging helper — please keep this around, even if not used */ + + _cleanup_free_ char16_t *hex = hexdump(data, size); + log_internal(EFI_SUCCESS, "%ls[%zu]: %ls", prefix, size, hex); +} +#endif + +void log_wait(void) { + if (log_count == 0) + return; + + BS->Stall(MIN(4u, log_count) * 2500 * 1000); + log_count = 0; +} + +_used_ intptr_t __stack_chk_guard = (intptr_t) 0x70f6967de78acae3; + +/* We can only set a random stack canary if this function attribute is available, + * otherwise this may create a stack check fail. */ +#if STACK_PROTECTOR_RANDOM +void __stack_chk_guard_init(void) { + EFI_RNG_PROTOCOL *rng; + if (BS->LocateProtocol(MAKE_GUID_PTR(EFI_RNG_PROTOCOL), NULL, (void **) &rng) == EFI_SUCCESS) + (void) rng->GetRNG(rng, NULL, sizeof(__stack_chk_guard), (void *) &__stack_chk_guard); + else + /* Better than no extra entropy. */ + __stack_chk_guard ^= (intptr_t) __executable_start; +} +#endif + +_used_ _noreturn_ void __stack_chk_fail(void); +_used_ _noreturn_ void __stack_chk_fail_local(void); +void __stack_chk_fail(void) { + panic(u"systemd-boot: Stack check failed, halting."); +} +void __stack_chk_fail_local(void) { + __stack_chk_fail(); +} + +/* Called by libgcc for some fatal errors like integer overflow with -ftrapv. */ +_used_ _noreturn_ void abort(void); +void abort(void) { + panic(u"systemd-boot: Unknown error, halting."); +} + +#if defined(__ARM_EABI__) +/* These override the (weak) div0 handlers from libgcc as they would otherwise call raise() instead. */ +_used_ _noreturn_ int __aeabi_idiv0(int return_value); +_used_ _noreturn_ long long __aeabi_ldiv0(long long return_value); + +int __aeabi_idiv0(int return_value) { + panic(u"systemd-boot: Division by zero, halting."); +} + +long long __aeabi_ldiv0(long long return_value) { + panic(u"systemd-boot: Division by zero, halting."); +} +#endif -- cgit v1.2.3