]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/boot/efi/util.h
Merge pull request #21981 from medhefgo/boot-cleanup
[thirdparty/systemd.git] / src / boot / efi / util.h
index 9eef51cc7e91da5f23e72343b120b04d6cb79e22..58ca44443da656b0c0d049a96236e2b373af1615 100644 (file)
@@ -6,11 +6,46 @@
 
 #include "string-util-fundamental.h"
 
-#define OFFSETOF(x,y) __builtin_offsetof(x,y)
+/* This TPM PCR is where most Linux infrastructure extends the kernel command line into, and so do we. We also extend
+ * any passed credentials here. */
+#define TPM_PCR_INDEX_KERNEL_PARAMETERS 8
 
-static inline UINTN ALIGN_TO(UINTN l, UINTN ali) {
-        return ((l + ali - 1) & ~(ali - 1));
-}
+/* This TPM PCR is where most Linux infrastructure extends the initrd binary images into, and so do we. */
+#define TPM_PCR_INDEX_INITRD 4
+
+#define offsetof(type, member) __builtin_offsetof(type, member)
+
+#define UINTN_MAX (~(UINTN)0)
+#define INTN_MAX ((INTN)(UINTN_MAX>>1))
+#ifndef UINT32_MAX
+#define UINT32_MAX ((UINT32) -1)
+#endif
+#ifndef UINT64_MAX
+#define UINT64_MAX ((UINT64) -1)
+#endif
+
+#define assert_alloc_ret(p)     \
+        ({                      \
+                void *_p = (p); \
+                assert(_p);     \
+                _p;             \
+        })
+
+#define xnew_alloc(type, n, alloc)                                           \
+        ({                                                                   \
+                UINTN _alloc_size;                                           \
+                if (__builtin_mul_overflow(sizeof(type), (n), &_alloc_size)) \
+                        assert_not_reached();                                \
+                (type *) alloc(_alloc_size);                                 \
+        })
+
+#define xallocate_pool(size) assert_alloc_ret(AllocatePool(size))
+#define xallocate_zero_pool(size) assert_alloc_ret(AllocateZeroPool(size))
+#define xreallocate_pool(p, old_size, new_size) assert_alloc_ret(ReallocatePool((p), (old_size), (new_size)))
+#define xpool_print(fmt, ...) ((CHAR16 *) assert_alloc_ret(PoolPrint((fmt), ##__VA_ARGS__)))
+#define xstrdup(str) ((CHAR16 *) assert_alloc_ret(StrDuplicate(str)))
+#define xnew(type, n) xnew_alloc(type, (n), xallocate_pool)
+#define xnew0(type, n) xnew_alloc(type, (n), xallocate_zero_pool)
 
 EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b);
 
@@ -19,11 +54,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);
@@ -33,12 +68,12 @@ EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
 EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret);
 
 CHAR8 *strchra(const CHAR8 *s, CHAR8 c);
-CHAR16 *stra_to_path(const CHAR8 *stra);
-CHAR16 *stra_to_str(const CHAR8 *stra);
+CHAR16 *xstra_to_path(const CHAR8 *stra);
+CHAR16 *xstra_to_str(const CHAR8 *stra);
 
 EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size);
 
-static inline void FreePoolp(void *p) {
+static inline void free_poolp(void *p) {
         void *q = *(void**) p;
 
         if (!q)
@@ -47,13 +82,13 @@ static inline void FreePoolp(void *p) {
         FreePool(q);
 }
 
-#define _cleanup_freepool_ _cleanup_(FreePoolp)
+#define _cleanup_freepool_ _cleanup_(free_poolp)
 
-static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) {
+static inline void file_handle_closep(EFI_FILE_HANDLE *handle) {
         if (!*handle)
                 return;
 
-        uefi_call_wrapper((*handle)->Close, 1, *handle);
+        (*handle)->Close(*handle);
 }
 
 /*
@@ -65,16 +100,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
 
-#define UINTN_MAX (~(UINTN)0)
-#define INTN_MAX ((INTN)(UINTN_MAX>>1))
-#ifndef UINT32_MAX
-#define UINT32_MAX ((UINT32) -1)
-#endif
-#ifndef UINT64_MAX
-#define UINT64_MAX ((UINT64) -1)
-#endif
-
-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
@@ -85,11 +111,61 @@ EFI_STATUS log_oom(void);
                 err; \
         })
 
-VOID *memmem_safe(const VOID *haystack, UINTN haystack_len, const VOID *needle, UINTN needle_len);
+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);
+
+EFI_STATUS get_file_info_harder(EFI_FILE_HANDLE handle, EFI_FILE_INFO **ret, UINTN *ret_size);
+
+EFI_STATUS readdir_harder(EFI_FILE_HANDLE handle, EFI_FILE_INFO **buffer, UINTN *buffer_size);
+
+UINTN strnlena(const CHAR8 *p, UINTN maxlen);
+CHAR8 *xstrndup8(const CHAR8 *p, UINTN sz);
+INTN strncasecmpa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen);
+static inline BOOLEAN strncaseeqa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen) {
+        return strncasecmpa(a, b, maxlen) == 0;
+}
+
+BOOLEAN is_ascii(const CHAR16 *f);
 
-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;
+CHAR16 **strv_free(CHAR16 **l);
+
+static inline void strv_freep(CHAR16 ***p) {
+        strv_free(*p);
+}
+
+EFI_STATUS open_directory(EFI_FILE_HANDLE root_dir, const CHAR16 *path, EFI_FILE_HANDLE *ret);
+
+/* Conversion between EFI_PHYSICAL_ADDRESS and pointers is not obvious. The former is always 64bit, even on
+ * 32bit archs. And gcc complains if we cast a pointer to an integer of a different size. Hence let's do the
+ * conversion indirectly: first into UINTN (which is defined by UEFI to have the same size as a pointer), and
+ * then extended to EFI_PHYSICAL_ADDRESS. */
+static inline EFI_PHYSICAL_ADDRESS POINTER_TO_PHYSICAL_ADDRESS(const void *p) {
+        return (EFI_PHYSICAL_ADDRESS) (UINTN) p;
+}
+
+static inline void *PHYSICAL_ADDRESS_TO_POINTER(EFI_PHYSICAL_ADDRESS addr) {
+#if __SIZEOF_POINTER__ == 4
+        /* On 32bit systems the address might not be convertible (as pointers are 32bit but
+         * EFI_PHYSICAL_ADDRESS 64bit) */
+        assert(addr <= UINT32_MAX);
+#elif __SIZEOF_POINTER__ != 8
+        #error "Unexpected pointer size"
+#endif
+
+        return (void*) (UINTN) addr;
 }
 
-VOID print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str);
+UINT64 get_os_indications_supported(void);
+
+#ifdef EFI_DEBUG
+void debug_break(void);
+extern UINT8 _text, _data;
+/* Report the relocated position of text and data sections so that a debugger
+ * can attach to us. See debug-sd-boot.sh for how this can be done. */
+#  define debug_hook(identity) Print(identity L"@0x%x,0x%x\n", &_text, &_data)
+#else
+#  define debug_hook(identity)
+#endif