third_party/efistub: update to use PE entry point

The old efistub used the EFI handover mechanism, which only exists for
x86_64. Since Linux 5.8 x86_64 also supports the standard PE entry point
which works the same for all supported architectures. That also has the
benefit of no longer needing a weird hack to switch to SysV ABI to call
into the kernel.

Change-Id: Icd75599758e09d888a31c31f07967dfc78356fca
Reviewed-on: https://review.monogon.dev/c/monogon/+/4213
Tested-by: Jenkins CI
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
diff --git a/third_party/efistub/efistub.bzl b/third_party/efistub/efistub.bzl
index d0e2a2f..5dc9696 100644
--- a/third_party/efistub/efistub.bzl
+++ b/third_party/efistub/efistub.bzl
@@ -8,16 +8,22 @@
         "cpio.c",
         "disk.c",
         "graphics.c",
+        "console.c",
+        "devicetree.c",
         "linux.c",
+        "linux_x86.c",
+        "initrd.c",
         "measure.c",
+        "ticks.c",
         "pe.c",
         "secure-boot.c",
         "splash.c",
         "stub.c",
+        "efi-string.c",
         "util.c",
     ]] + glob(["src/boot/efi/*.h", "src/fundamental/*.c", "src/fundamental/*.h"]),
-    includes = ["src/fundamental"],
-    copts = ["-std=gnu99", "-DSD_BOOT", "-DGIT_VERSION=\\\"0.0.0-mngn\\\""],
+    includes = ["src/fundamental", "src/boot/efi"],
+    copts = ["-std=gnu11", "-O2", "-DSD_BOOT", "-DGIT_VERSION=\\\"0.0.0-mngn\\\""],
     deps = ["@gnuefi//:gnuefi"],
     target_compatible_with = [
         "@platforms//os:uefi",
diff --git a/third_party/efistub/patches/ab-slot-handling.patch b/third_party/efistub/patches/ab-slot-handling.patch
index 0e5f369..60ee3ef 100644
--- a/third_party/efistub/patches/ab-slot-handling.patch
+++ b/third_party/efistub/patches/ab-slot-handling.patch
@@ -1,38 +1,38 @@
-From a8004bca64e697bf8f39af63c4325fbc9b507e48 Mon Sep 17 00:00:00 2001
+From 24a496c861fff6f8633453eedb92079976d3058f Mon Sep 17 00:00:00 2001
 From: Lorenz Brun <lorenz@monogon.tech>
 Date: Thu, 29 Jun 2023 03:54:01 +0200
-Subject: [PATCH] Implement filename-based A/B slot handling
+Subject: [PATCH 1/2] Implement filename-based A/B slot handling
 
 ---
  src/boot/efi/stub.c | 66 +++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 66 insertions(+)
 
 diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
-index dad0f61335..88eda7e0e7 100644
+index 841a0e41bd..267ecbcc81 100644
 --- a/src/boot/efi/stub.c
 +++ b/src/boot/efi/stub.c
-@@ -5,6 +5,8 @@
- 
+@@ -6,6 +6,8 @@
  #include "cpio.h"
+ #include "devicetree.h"
  #include "disk.h"
 +#include "efibind.h"
 +#include "efidevp.h"
  #include "graphics.h"
  #include "linux.h"
  #include "measure.h"
-@@ -13,6 +15,31 @@
- #include "splash.h"
+@@ -15,6 +17,31 @@
+ #include "tpm-pcr.h"
  #include "util.h"
  
 +// From picolibc under BSD-3-Clause (c) 2018 Arm Ltd.
 +/* Small and efficient strstr implementation.  */
-+char * strstr (const char *hs, const char *ne)
++char16_t * strstr (const char16_t *hs, const char16_t *ne)
 +{
 +  UINTN i;
 +  int c = ne[0];
 +
 +  if (c == 0)
-+    return (char*)hs;
++    return (char16_t*)hs;
 +
 +  for ( ; hs[0] != '\0'; hs++)
 +    {
@@ -42,7 +42,7 @@
 +	if (hs[i] != ne[i])
 +	  break;
 +      if (ne[i] == '\0')
-+	return (char*)hs;
++	return (char16_t*)hs;
 +    }
 +
 +  return NULL;
@@ -50,10 +50,10 @@
 +
 +
  /* magic string to find in the binary image */
- static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
+ _used_ _section_(".sdmagic") static const char magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
  
-@@ -180,6 +207,45 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
-                 cmdline_len = szs[SECTION_CMDLINE];
+@@ -232,6 +259,45 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
+                 mangle_stub_cmdline(cmdline);
          }
  
 +        /* Extract last FILEPATH element from image path to check file name */
@@ -67,37 +67,37 @@
 +                current_path_elem = NextDevicePathNode(current_path_elem);
 +        }
 +        /* Check slot based on suffix of the last FILE_PATH value */
-+        CHAR8 slot = 'A';
-+        const CHAR16 suffix_a[] = L"boot-a.efi";
-+        const CHAR16 suffix_b[] = L"boot-b.efi";
-+        const UINTN suffix_len = (sizeof(suffix_a)/sizeof(CHAR16))-1;
++        char16_t slot = 'A';
++        const char16_t suffix_a[] = u"boot-a.efi";
++        const char16_t suffix_b[] = u"boot-b.efi";
++        const UINTN suffix_len = (sizeof(suffix_a)/sizeof(char16_t))-1;
 +        if (last_file_path != NULL) {
 +                UINTN plen = StrLen(last_file_path);
 +                if (suffix_len > plen) {
-+                        // TODO: Log
-+                } else if (StriCmp(suffix_a, last_file_path + (plen-suffix_len)) == 0) {
++                        Print(L"File name too short, blindly booting slot A\n");
++                } else if (StriCmp(suffix_a, &last_file_path[plen-suffix_len]) == 0){
 +                        slot = 'A';
-+                } else if (StriCmp(suffix_b, last_file_path + (plen-suffix_len)) == 0) {
++                } else if (StriCmp(suffix_b, &last_file_path[plen-suffix_len]) == 0) {
 +                        slot = 'B';
 +                } else {
-+                        // TODO: Log
++                        Print(L"Unknown file name, blindly booting slot A\n");
 +                }
 +        }
 +        Print(L"Booting into Slot %c\n", slot);
 +        /* Replace METROPOLIS-SYSTEM-X with the correct slot */
-+        const char slot_identifier[] = "METROPOLIS-SYSTEM-X";
-+        const UINTN slot_id_len = (sizeof(slot_identifier)/sizeof(char))-1;
++        const char16_t slot_identifier[] = u"METROPOLIS-SYSTEM-X\0";
++        const UINTN slot_id_len = (sizeof(slot_identifier)/sizeof(char16_t))-1;
 +        if (cmdline != NULL) {
-+                CHAR8 *rest_ptr = cmdline;
++                char16_t *rest_ptr = cmdline;
 +                while((rest_ptr = strstr(rest_ptr, slot_identifier))) {
-+                        rest_ptr[slot_id_len-1] = slot;
++                        rest_ptr[slot_id_len-2] = slot;
 +                        rest_ptr += slot_id_len;
-+                }
++                }                
 +        }
 +
-         /* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */
-         if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 &&
-             *(CHAR16 *) loaded_image->LoadOptions > 0x1F) {
+         export_variables(loaded_image);
+ 
+         if (pack_cpio(loaded_image,
 -- 
-2.40.1
+2.47.2
 
diff --git a/third_party/efistub/patches/use-local-uchar.patch b/third_party/efistub/patches/use-local-uchar.patch
new file mode 100644
index 0000000..a215619
--- /dev/null
+++ b/third_party/efistub/patches/use-local-uchar.patch
@@ -0,0 +1,212 @@
+From e14a6121d78dad23e3826499177353f9596ba0d7 Mon Sep 17 00:00:00 2001
+From: Lorenz Brun <lorenz@brun.one>
+Date: Thu, 22 May 2025 18:22:18 +0200
+Subject: [PATCH 2/2] Use local uchar.h
+
+---
+ src/boot/efi/bcd.h                    | 2 +-
+ src/boot/efi/cpio.c                   | 2 ++
+ src/boot/efi/cpio.h                   | 2 +-
+ src/boot/efi/devicetree.h             | 2 +-
+ src/boot/efi/disk.h                   | 2 +-
+ src/boot/efi/efi-string.h             | 2 +-
+ src/boot/efi/linux.h                  | 3 ++-
+ src/boot/efi/measure.h                | 2 +-
+ src/boot/efi/pe.h                     | 2 +-
+ src/boot/efi/secure-boot.c            | 2 +-
+ src/boot/efi/stub.c                   | 1 +
+ src/boot/efi/uchar.h                  | 6 ++++++
+ src/boot/efi/util.h                   | 2 +-
+ src/fundamental/efivars-fundamental.h | 3 +--
+ 14 files changed, 21 insertions(+), 12 deletions(-)
+ create mode 100644 src/boot/efi/uchar.h
+
+diff --git a/src/boot/efi/bcd.h b/src/boot/efi/bcd.h
+index c27af55c1e..17d79caf20 100644
+--- a/src/boot/efi/bcd.h
++++ b/src/boot/efi/bcd.h
+@@ -2,6 +2,6 @@
+ #pragma once
+ 
+ #include <stdint.h>
+-#include <uchar.h>
++#include "uchar.h"
+ 
+ char16_t *get_bcd_title(uint8_t *bcd, size_t bcd_len);
+diff --git a/src/boot/efi/cpio.c b/src/boot/efi/cpio.c
+index 76e2cd7f4e..5c2f68c2dc 100644
+--- a/src/boot/efi/cpio.c
++++ b/src/boot/efi/cpio.c
+@@ -1,5 +1,7 @@
+ /* SPDX-License-Identifier: LGPL-2.1-or-later */
+ 
++#include <stddef.h>
++
+ #include "cpio.h"
+ #include "measure.h"
+ #include "util.h"
+diff --git a/src/boot/efi/cpio.h b/src/boot/efi/cpio.h
+index beebef3d8b..90ed8cd025 100644
+--- a/src/boot/efi/cpio.h
++++ b/src/boot/efi/cpio.h
+@@ -3,7 +3,7 @@
+ 
+ #include <efi.h>
+ #include <stdbool.h>
+-#include <uchar.h>
++#include "uchar.h"
+ 
+ EFI_STATUS pack_cpio(
+                 EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
+diff --git a/src/boot/efi/devicetree.h b/src/boot/efi/devicetree.h
+index d512cb5037..f3c6de78ba 100644
+--- a/src/boot/efi/devicetree.h
++++ b/src/boot/efi/devicetree.h
+@@ -2,7 +2,7 @@
+ #pragma once
+ 
+ #include <efi.h>
+-#include <uchar.h>
++#include "uchar.h"
+ 
+ struct devicetree_state {
+         EFI_PHYSICAL_ADDRESS addr;
+diff --git a/src/boot/efi/disk.h b/src/boot/efi/disk.h
+index 1a5a18733e..6f6b517a16 100644
+--- a/src/boot/efi/disk.h
++++ b/src/boot/efi/disk.h
+@@ -2,6 +2,6 @@
+ #pragma once
+ 
+ #include <efi.h>
+-#include <uchar.h>
++#include "uchar.h"
+ 
+ EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, char16_t uuid[static 37]);
+diff --git a/src/boot/efi/efi-string.h b/src/boot/efi/efi-string.h
+index e12add0b19..a6c8b0c56a 100644
+--- a/src/boot/efi/efi-string.h
++++ b/src/boot/efi/efi-string.h
+@@ -3,7 +3,7 @@
+ 
+ #include <stdbool.h>
+ #include <stddef.h>
+-#include <uchar.h>
++#include "uchar.h"
+ 
+ #include "macro-fundamental.h"
+ 
+diff --git a/src/boot/efi/linux.h b/src/boot/efi/linux.h
+index f0a6a37ed1..f1b7ff851f 100644
+--- a/src/boot/efi/linux.h
++++ b/src/boot/efi/linux.h
+@@ -2,7 +2,8 @@
+ #pragma once
+ 
+ #include <efi.h>
+-#include <uchar.h>
++#include "uchar.h"
++#include <stddef.h>
+ 
+ EFI_STATUS linux_exec(
+                 EFI_HANDLE parent,
+diff --git a/src/boot/efi/measure.h b/src/boot/efi/measure.h
+index 19a50f47e7..9db41ab5ce 100644
+--- a/src/boot/efi/measure.h
++++ b/src/boot/efi/measure.h
+@@ -3,7 +3,7 @@
+ 
+ #include <efi.h>
+ #include <stdbool.h>
+-#include <uchar.h>
++#include "uchar.h"
+ 
+ #if ENABLE_TPM
+ 
+diff --git a/src/boot/efi/pe.h b/src/boot/efi/pe.h
+index ff7ff479ec..ef56cbbee9 100644
+--- a/src/boot/efi/pe.h
++++ b/src/boot/efi/pe.h
+@@ -2,7 +2,7 @@
+ #pragma once
+ 
+ #include <efidef.h>
+-#include <uchar.h>
++#include "uchar.h"
+ 
+ EFI_STATUS pe_memory_locate_sections(
+                 const void *base,
+diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c
+index 65457bf423..f65330f396 100644
+--- a/src/boot/efi/secure-boot.c
++++ b/src/boot/efi/secure-boot.c
+@@ -41,7 +41,7 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path) {
+ 
+         EFI_STATUS err;
+ 
+-        clear_screen(COLOR_NORMAL);
++        //clear_screen(COLOR_NORMAL);
+ 
+         Print(L"Enrolling secure boot keys from directory: %s\n"
+               L"Warning: Enrolling custom Secure Boot keys might soft-brick your machine!\n",
+diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
+index af80f17f81..f6b4cf060c 100644
+--- a/src/boot/efi/stub.c
++++ b/src/boot/efi/stub.c
+@@ -2,6 +2,7 @@
+ 
+ #include <efi.h>
+ #include <efilib.h>
++#include <stddef.h>
+ 
+ #include "cpio.h"
+ #include "devicetree.h"
+diff --git a/src/boot/efi/uchar.h b/src/boot/efi/uchar.h
+new file mode 100644
+index 0000000000..e4c0e6836b
+--- /dev/null
++++ b/src/boot/efi/uchar.h
+@@ -0,0 +1,6 @@
++#pragma once
++
++/** The UTF-16 character type. */
++typedef __CHAR16_TYPE__ char16_t;
++/** The UTF-32 character type. */
++typedef __CHAR32_TYPE__ char32_t;
+diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
+index 08f732f484..a10e74f569 100644
+--- a/src/boot/efi/util.h
++++ b/src/boot/efi/util.h
+@@ -54,7 +54,7 @@ static inline void freep(void *p) {
+ 
+ #define _cleanup_free_ _cleanup_(freep)
+ 
+-static __always_inline void erase_obj(void *p) {
++static __attribute__((always_inline)) void erase_obj(void *p) {
+ #ifdef __OPTIMIZE__
+         size_t l;
+         assert_cl(p);
+diff --git a/src/fundamental/efivars-fundamental.h b/src/fundamental/efivars-fundamental.h
+index fe34e6c714..5d0fc701af 100644
+--- a/src/fundamental/efivars-fundamental.h
++++ b/src/fundamental/efivars-fundamental.h
+@@ -1,7 +1,6 @@
+ /* SPDX-License-Identifier: LGPL-2.1-or-later */
+ #pragma once
+ 
+-#include <errno.h>
+ #include "string-util-fundamental.h"
+ 
+ /* Features of the loader, i.e. systemd-boot */
+@@ -32,7 +31,7 @@ typedef enum SecureBootMode {
+         SECURE_BOOT_SETUP,
+         SECURE_BOOT_USER,
+         _SECURE_BOOT_MAX,
+-        _SECURE_BOOT_INVALID = -EINVAL,
++        _SECURE_BOOT_INVALID = -22,
+ } SecureBootMode;
+ 
+ const sd_char *secure_boot_mode_to_string(SecureBootMode m);
+-- 
+2.47.2
+