]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add malloc attribute to memory allocation functions
authorDiego Fronza <diego@isc.org>
Thu, 1 Apr 2021 20:03:59 +0000 (17:03 -0300)
committerDiego Fronza <diego@isc.org>
Mon, 26 Apr 2021 14:32:17 +0000 (11:32 -0300)
The malloc attribute allows compiler to do some optmizations on
functions that behave like malloc/calloc, like assuming that the
returned pointer do not alias other pointers.

configure.ac
lib/isc/include/isc/attributes.h
lib/isc/include/isc/mem.h

index 232d88f0c688d7c249f128f360cb4b1b9d8d0ee1..a53e70ec1c30d2fc7030a9706ba879a845daaa91 100644 (file)
@@ -422,6 +422,34 @@ AC_COMPILE_IFELSE(
 #
 AX_GCC_FUNC_ATTRIBUTE([noreturn])
 
+#
+# check for GCC malloc attribute
+#
+AX_GCC_FUNC_ATTRIBUTE([malloc])
+
+AC_MSG_CHECKING([for extended malloc attributes])
+AC_COMPILE_IFELSE(
+  [AC_LANG_PROGRAM(
+     [[
+       #include <stddef.h>
+       #include <stdlib.h>
+          __attribute__ ((malloc, malloc (free, 1))
+          void * xmalloc(size_t sz) { return malloc(sz); }
+     ]],
+     [[
+       void *p = xmalloc(8);
+          free(p);
+     ]])],
+  [AC_MSG_RESULT(yes)
+   AC_DEFINE([HAVE_MALLOC_EXT_ATTR], [1], [define if extended attributes for malloc are available])
+  ],
+  [AC_MSG_RESULT(no)])
+
+#
+# check for GCC returns_nonnull attribute
+#
+AX_GCC_FUNC_ATTRIBUTE([returns_nonnull])
+
 #
 # check if we have kqueue
 #
index d4a07bfec96ae3ed8e9c2e0bfbd79c85a7ee2458..ab7315ad91c28766af52c714fb908009d062d05d 100644 (file)
 #else
 #define ISC_NORETURN
 #endif
+
+#if HAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL
+#define ISC_ATTR_RETURNS_NONNULL __attribute__((returns_nonnull))
+#else
+#define ISC_ATTR_RETURNS_NONNULL
+#endif
+
+#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
+/*
+ * Indicates that a function is malloc-like, i.e., that the
+ * pointer P returned by the function cannot alias any other
+ * pointer valid when the function returns.
+ */
+#define ISC_ATTR_MALLOC __attribute__((malloc))
+#if HAVE_MALLOC_EXT_ATTR
+/*
+ * Associates deallocator as a suitable deallocation function
+ * for pointers returned from the function marked with the attribute.
+ */
+#define ISC_ATTR_DEALLOCATOR(deallocator) __attribute__((malloc(deallocator)))
+/*
+ * Similar to ISC_ATTR_DEALLOCATOR, but allows to speficy an index "idx",
+ * which denotes the positional argument to which when the pointer is passed
+ * in calls to deallocator has the effect of deallocating it.
+ */
+#define ISC_ATTR_DEALLOCATOR_IDX(deallocator, idx) \
+       __attribute__((malloc(deallocator, idx)))
+/*
+ * Combines both ISC_ATTR_MALLOC and ISC_ATTR_DEALLOCATOR attributes.
+ */
+#define ISC_ATTR_MALLOC_DEALLOCATOR(deallocator) \
+       __attribute__((malloc, malloc(deallocator)))
+/*
+ * Similar to ISC_ATTR_MALLOC_DEALLOCATOR, but allows to speficy an index "idx",
+ * which denotes the positional argument to which when the pointer is passed
+ * in calls to deallocator has the effect of deallocating it.
+ */
+#define ISC_ATTR_MALLOC_DEALLOCATOR_IDX(deallocator, idx) \
+       __attribute__((malloc, malloc(deallocator, idx)))
+#else /* #ifdef HAVE_MALLOC_EXT_ATTR */
+/*
+ * There is support for malloc attribute but not for
+ * extended attributes, so macros that combine attribute malloc
+ * with a deallocator will only expand to malloc attribute.
+ */
+#define ISC_ATTR_DEALLOCATOR(deallocator)
+#define ISC_ATTR_DEALLOCATOR_IDX(deallocator, idx)
+#define ISC_ATTR_MALLOC_DEALLOCATOR(deallocator)         ISC_ATTR_MALLOC
+#define ISC_ATTR_MALLOC_DEALLOCATOR_IDX(deallocator, idx) ISC_ATTR_MALLOC
+#endif
+#else /* #ifdef HAVE_FUNC_ATTRIBUTE_MALLOC */
+/*
+ * There is no support for malloc attribute.
+ */
+#define ISC_ATTR_MALLOC
+#define ISC_ATTR_DEALLOCATOR(deallocator)
+#define ISC_ATTR_DEALLOCATOR_IDX(deallocator, idx)
+#define ISC_ATTR_MALLOC_DEALLOCATOR(deallocator)
+#define ISC_ATTR_MALLOC_DEALLOCATOR_IDX(deallocator, idx)
+#endif /* HAVE_FUNC_ATTRIBUTE_MALLOC */
\ No newline at end of file
index 1d274316dd625aa73aeec4ca6d1330d090d387d3..a8a5c5dcd341fc8d5bed0110c91f51f40a7e9c42 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 
+#include <isc/attributes.h>
 #include <isc/lang.h>
 #include <isc/mutex.h>
 #include <isc/platform.h>
@@ -508,19 +509,54 @@ isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
  *\li  limit > 0
  */
 
+#if defined(UNIT_TESTING) && defined(malloc)
+/*
+ * cmocka.h redefined malloc as a macro, we #undef it
+ * to avoid replacing ISC_ATTR_MALLOC with garbage.
+ */
+#pragma push_macro("malloc")
+#undef malloc
+#define POP_MALLOC_MACRO 1
+#endif
+
 /*
  * Pseudo-private functions for use via macros.  Do not call directly.
  */
+void ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG);
+void ISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
+void ISCMEMFUNC(free)(isc_mem_t *, void *_ISC_MEM_FLARG);
+
+ISC_ATTR_RETURNS_NONNULL
+ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(put), 2)
 void *ISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG);
-void  ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG);
-void  ISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
+
+ISC_ATTR_RETURNS_NONNULL
+ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
 void *ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG);
+
+ISC_ATTR_RETURNS_NONNULL
+ISC_ATTR_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
 void *ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
-void  ISCMEMFUNC(free)(isc_mem_t *, void *_ISC_MEM_FLARG);
+
+ISC_ATTR_RETURNS_NONNULL
+ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
 char *ISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG);
+
+ISC_ATTR_RETURNS_NONNULL
+ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
 char *ISCMEMFUNC(strndup)(isc_mem_t *, const char *, size_t _ISC_MEM_FLARG);
+
+ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMPOOLFUNC(put), 2)
 void *ISCMEMPOOLFUNC(get)(isc_mempool_t *_ISC_MEM_FLARG);
-void  ISCMEMPOOLFUNC(put)(isc_mempool_t *, void *_ISC_MEM_FLARG);
+
+void ISCMEMPOOLFUNC(put)(isc_mempool_t *, void *_ISC_MEM_FLARG);
+
+#ifdef POP_MALLOC_MACRO
+/*
+ * Restore cmocka.h macro for malloc.
+ */
+#pragma pop_macro("malloc")
+#endif
 
 ISC_LANG_ENDDECLS