]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Add xmalloc
authorJan Janssen <medhefgo@web.de>
Sat, 28 May 2022 17:29:41 +0000 (19:29 +0200)
committerJan Janssen <medhefgo@web.de>
Thu, 9 Jun 2022 10:50:13 +0000 (12:50 +0200)
src/boot/efi/util.h
src/fundamental/macro-fundamental.h

index 75d3e51415ebb6ee559fbad3bf40077b0c4285b3..2245c21ce764f59058078b6972395ffdc916c5be 100644 (file)
@@ -30,6 +30,48 @@ assert_cc(sizeof(int) == sizeof(UINT32));
 #  error "Unexpected pointer size"
 #endif
 
+static inline void free(void *p) {
+        if (!p)
+                return;
+
+        /* Debugging an invalid free requires trace logging to find the call site or a debugger attached. For
+         * release builds it is not worth the bother to even warn when we cannot even print a call stack. */
+#ifdef EFI_DEBUG
+        assert_se(BS->FreePool(p) == EFI_SUCCESS);
+#else
+        (void) BS->FreePool(p);
+#endif
+}
+
+static inline void freep(void *p) {
+        free(*(void **) p);
+}
+
+#define _cleanup_freepool_ _cleanup_free_
+#define _cleanup_free_ _cleanup_(freep)
+
+_malloc_ _alloc_(1) _returns_nonnull_ _warn_unused_result_
+static inline void *xmalloc(size_t size) {
+        void *p;
+        assert_se(BS->AllocatePool(EfiBootServicesData, size, &p) == EFI_SUCCESS);
+        return p;
+}
+
+_malloc_ _alloc_(1, 2) _returns_nonnull_ _warn_unused_result_
+static inline void *xmalloc_multiply(size_t size, size_t n) {
+        assert_se(!__builtin_mul_overflow(size, n, &size));
+        return xmalloc(size);
+}
+
+/* Use malloc attribute as this never returns p like userspace realloc. */
+_malloc_ _alloc_(3) _returns_nonnull_ _warn_unused_result_
+static inline void *xrealloc(void *p, size_t old_size, size_t new_size) {
+        void *r = xmalloc(new_size);
+        memcpy(r, p, MIN(old_size, new_size));
+        free(p);
+        return r;
+}
+
 #define xnew_alloc(type, n, alloc)                                           \
         ({                                                                   \
                 UINTN _alloc_size;                                           \
@@ -65,17 +107,6 @@ CHAR16 *xstra_to_str(const CHAR8 *stra);
 
 EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size);
 
-static inline void free_poolp(void *p) {
-        void *q = *(void**) p;
-
-        if (!q)
-                return;
-
-        (void) BS->FreePool(q);
-}
-
-#define _cleanup_freepool_ _cleanup_(free_poolp)
-
 static inline void file_closep(EFI_FILE **handle) {
         if (!*handle)
                 return;
index f78c62ef250b3c2b5f097c7a60b303ef88d71e51..18370ac46a7cc926818f25c6af1823370bfcbfeb 100644 (file)
@@ -25,6 +25,7 @@
 #define _public_ __attribute__((__visibility__("default")))
 #define _pure_ __attribute__((__pure__))
 #define _retain_ __attribute__((__retain__))
+#define _returns_nonnull_ __attribute__((__returns_nonnull__))
 #define _section_(x) __attribute__((__section__(x)))
 #define _sentinel_ __attribute__((__sentinel__))
 #define _unlikely_(x) (__builtin_expect(!!(x), 0))
@@ -76,8 +77,6 @@
         #endif
         #define static_assert _Static_assert
         #define assert_se(expr) ({ _likely_(expr) ? VOID_0 : efi_assert(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); })
-
-        #define free(a) FreePool(a)
 #endif
 
 /* This passes the argument through after (if asserts are enabled) checking that it is not null. */