1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
7 #include "string-util-fundamental.h"
9 /* This TPM PCR is where most Linux infrastructure extends the kernel command line into, and so do we. We also extend
10 * any passed credentials here. */
11 #define TPM_PCR_INDEX_KERNEL_PARAMETERS 8
13 /* This TPM PCR is where most Linux infrastructure extends the initrd binary images into, and so do we. */
14 #define TPM_PCR_INDEX_INITRD 4
16 #define OFFSETOF(x,y) __builtin_offsetof(x,y)
18 #define UINTN_MAX (~(UINTN)0)
19 #define INTN_MAX ((INTN)(UINTN_MAX>>1))
21 #define UINT32_MAX ((UINT32) -1)
24 #define UINT64_MAX ((UINT64) -1)
27 #define assert_alloc_ret(p) \
34 #define xnew_alloc(type, n, alloc) \
37 if (__builtin_mul_overflow(sizeof(type), (n), &_alloc_size)) \
38 assert_not_reached(); \
39 (type *) alloc(_alloc_size); \
42 #define xallocate_pool(size) assert_alloc_ret(AllocatePool(size))
43 #define xallocate_zero_pool(size) assert_alloc_ret(AllocateZeroPool(size))
44 #define xreallocate_pool(p, old_size, new_size) assert_alloc_ret(ReallocatePool((p), (old_size), (new_size)))
45 #define xpool_print(fmt, ...) ((CHAR16 *) assert_alloc_ret(PoolPrint((fmt), ##__VA_ARGS__)))
46 #define xstrdup(str) ((CHAR16 *) assert_alloc_ret(StrDuplicate(str)))
47 #define xnew(type, n) xnew_alloc(type, (n), xallocate_pool)
48 #define xnew0(type, n) xnew_alloc(type, (n), xallocate_zero_pool)
50 EFI_STATUS
parse_boolean(const CHAR8
*v
, BOOLEAN
*b
);
52 UINT64
ticks_read(void);
53 UINT64
ticks_freq(void);
54 UINT64
time_usec(void);
56 EFI_STATUS
efivar_set(const EFI_GUID
*vendor
, const CHAR16
*name
, const CHAR16
*value
, UINT32 flags
);
57 EFI_STATUS
efivar_set_raw(const EFI_GUID
*vendor
, const CHAR16
*name
, const void *buf
, UINTN size
, UINT32 flags
);
58 EFI_STATUS
efivar_set_uint_string(const EFI_GUID
*vendor
, const CHAR16
*name
, UINTN i
, UINT32 flags
);
59 EFI_STATUS
efivar_set_uint32_le(const EFI_GUID
*vendor
, const CHAR16
*NAME
, UINT32 value
, UINT32 flags
);
60 EFI_STATUS
efivar_set_uint64_le(const EFI_GUID
*vendor
, const CHAR16
*name
, UINT64 value
, UINT32 flags
);
61 void efivar_set_time_usec(const EFI_GUID
*vendor
, const CHAR16
*name
, UINT64 usec
);
63 EFI_STATUS
efivar_get(const EFI_GUID
*vendor
, const CHAR16
*name
, CHAR16
**value
);
64 EFI_STATUS
efivar_get_raw(const EFI_GUID
*vendor
, const CHAR16
*name
, CHAR8
**buffer
, UINTN
*size
);
65 EFI_STATUS
efivar_get_uint_string(const EFI_GUID
*vendor
, const CHAR16
*name
, UINTN
*i
);
66 EFI_STATUS
efivar_get_uint32_le(const EFI_GUID
*vendor
, const CHAR16
*name
, UINT32
*ret
);
67 EFI_STATUS
efivar_get_uint64_le(const EFI_GUID
*vendor
, const CHAR16
*name
, UINT64
*ret
);
68 EFI_STATUS
efivar_get_boolean_u8(const EFI_GUID
*vendor
, const CHAR16
*name
, BOOLEAN
*ret
);
70 CHAR8
*strchra(const CHAR8
*s
, CHAR8 c
);
71 CHAR16
*xstra_to_path(const CHAR8
*stra
);
72 CHAR16
*xstra_to_str(const CHAR8
*stra
);
74 EFI_STATUS
file_read(EFI_FILE_HANDLE dir
, const CHAR16
*name
, UINTN off
, UINTN size
, CHAR8
**content
, UINTN
*content_size
);
76 static inline void FreePoolp(void *p
) {
77 void *q
= *(void**) p
;
85 #define _cleanup_freepool_ _cleanup_(FreePoolp)
87 static inline void FileHandleClosep(EFI_FILE_HANDLE
*handle
) {
91 (*handle
)->Close(*handle
);
95 * Allocated random UUID, intended to be shared across tools that implement
96 * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
97 * associated EFI variables.
100 &(const EFI_GUID) { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
101 #define EFI_GLOBAL_GUID &(const EFI_GUID) EFI_GLOBAL_VARIABLE
103 void log_error_stall(const CHAR16
*fmt
, ...);
104 EFI_STATUS
log_oom(void);
106 /* This works just like log_error_errno() from userspace, but requires you
107 * to provide err a second time if you want to use %r in the message! */
108 #define log_error_status_stall(err, fmt, ...) \
110 log_error_stall(fmt, ##__VA_ARGS__); \
114 void *memmem_safe(const void *haystack
, UINTN haystack_len
, const void *needle
, UINTN needle_len
);
116 static inline void *mempmem_safe(const void *haystack
, UINTN haystack_len
, const void *needle
, UINTN needle_len
) {
117 CHAR8
*p
= memmem_safe(haystack
, haystack_len
, needle
, needle_len
);
118 return p
? p
+ needle_len
: NULL
;
121 void print_at(UINTN x
, UINTN y
, UINTN attr
, const CHAR16
*str
);
122 void clear_screen(UINTN attr
);
124 typedef INTN (*compare_pointer_func_t
)(const void *a
, const void *b
);
125 void sort_pointer_array(void **array
, UINTN n_members
, compare_pointer_func_t compare
);
127 EFI_STATUS
get_file_info_harder(EFI_FILE_HANDLE handle
, EFI_FILE_INFO
**ret
, UINTN
*ret_size
);
129 EFI_STATUS
readdir_harder(EFI_FILE_HANDLE handle
, EFI_FILE_INFO
**buffer
, UINTN
*buffer_size
);
131 UINTN
strnlena(const CHAR8
*p
, UINTN maxlen
);
132 CHAR8
*xstrndup8(const CHAR8
*p
, UINTN sz
);
134 BOOLEAN
is_ascii(const CHAR16
*f
);
136 CHAR16
**strv_free(CHAR16
**l
);
138 static inline void strv_freep(CHAR16
***p
) {
142 EFI_STATUS
open_directory(EFI_FILE_HANDLE root_dir
, const CHAR16
*path
, EFI_FILE_HANDLE
*ret
);
144 /* Conversion between EFI_PHYSICAL_ADDRESS and pointers is not obvious. The former is always 64bit, even on
145 * 32bit archs. And gcc complains if we cast a pointer to an integer of a different size. Hence let's do the
146 * conversion indirectly: first into UINTN (which is defined by UEFI to have the same size as a pointer), and
147 * then extended to EFI_PHYSICAL_ADDRESS. */
148 static inline EFI_PHYSICAL_ADDRESS
POINTER_TO_PHYSICAL_ADDRESS(const void *p
) {
149 return (EFI_PHYSICAL_ADDRESS
) (UINTN
) p
;
152 static inline void *PHYSICAL_ADDRESS_TO_POINTER(EFI_PHYSICAL_ADDRESS addr
) {
153 #if __SIZEOF_POINTER__ == 4
154 /* On 32bit systems the address might not be convertible (as pointers are 32bit but
155 * EFI_PHYSICAL_ADDRESS 64bit) */
156 assert(addr
<= UINT32_MAX
);
157 #elif __SIZEOF_POINTER__ != 8
158 #error "Unexpected pointer size"
161 return (void*) (UINTN
) addr
;
164 UINT64
get_os_indications_supported(void);