malloc: add alloc_size attribute to functions
authorStephen Hemminger <stephen@networkplumber.org>
Thu, 15 Oct 2020 00:55:24 +0000 (17:55 -0700)
committerThomas Monjalon <thomas@monjalon.net>
Mon, 19 Oct 2020 14:25:43 +0000 (16:25 +0200)
By using the alloc_size() attribute the compiler can optimize
better and detect errors at compile time.

For example, Gcc will fail one of the invalid allocation examples
in app/test/test_malloc.c because the allocation is outside the
limits of memory.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
app/test/test_malloc.c
lib/librte_eal/include/rte_common.h
lib/librte_eal/include/rte_malloc.h

index 71b3cfd..fdf77b4 100644 (file)
@@ -846,6 +846,9 @@ test_malloc_bad_params(void)
        if (bad_ptr != NULL)
                goto err_return;
 
+#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
+       /* this test can not be built, will get trapped at compile time! */
+#else
        /* rte_malloc expected to return null with size will cause overflow */
        align = RTE_CACHE_LINE_SIZE;
        size = (size_t)-8;
@@ -857,7 +860,7 @@ test_malloc_bad_params(void)
        bad_ptr = rte_realloc(NULL, size, align);
        if (bad_ptr != NULL)
                goto err_return;
-
+#endif
        return 0;
 
 err_return:
index 2920255..e63ef0f 100644 (file)
@@ -134,6 +134,18 @@ typedef uint16_t unaligned_uint16_t;
        __attribute__((format(printf, format_index, first_arg)))
 #endif
 
+/**
+ * Tells compiler that the function returns a value that points to
+ * memory, where the size is given by the one or two arguments.
+ * Used by compiler to validate object size.
+ */
+#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
+#define __rte_alloc_size(...) \
+       __attribute__((alloc_size(__VA_ARGS__)))
+#else
+#define __rte_alloc_size(...)
+#endif
+
 #define RTE_PRIORITY_LOG 101
 #define RTE_PRIORITY_BUS 110
 #define RTE_PRIORITY_CLASS 120
index 42ca051..3af64f8 100644 (file)
@@ -54,7 +54,8 @@ struct rte_malloc_socket_stats {
  *   - Otherwise, the pointer to the allocated object.
  */
 void *
-rte_malloc(const char *type, size_t size, unsigned align);
+rte_malloc(const char *type, size_t size, unsigned align)
+       __rte_alloc_size(2);
 
 /**
  * Allocate zero'ed memory from the heap.
@@ -80,7 +81,8 @@ rte_malloc(const char *type, size_t size, unsigned align);
  *   - Otherwise, the pointer to the allocated object.
  */
 void *
-rte_zmalloc(const char *type, size_t size, unsigned align);
+rte_zmalloc(const char *type, size_t size, unsigned align)
+       __rte_alloc_size(2);
 
 /**
  * Replacement function for calloc(), using huge-page memory. Memory area is
@@ -106,7 +108,8 @@ rte_zmalloc(const char *type, size_t size, unsigned align);
  *   - Otherwise, the pointer to the allocated object.
  */
 void *
-rte_calloc(const char *type, size_t num, size_t size, unsigned align);
+rte_calloc(const char *type, size_t num, size_t size, unsigned align)
+       __rte_alloc_size(2, 3);
 
 /**
  * Replacement function for realloc(), using huge-page memory. Reserved area
@@ -129,7 +132,8 @@ rte_calloc(const char *type, size_t num, size_t size, unsigned align);
  *   - Otherwise, the pointer to the reallocated memory.
  */
 void *
-rte_realloc(void *ptr, size_t size, unsigned int align);
+rte_realloc(void *ptr, size_t size, unsigned int align)
+       __rte_alloc_size(2);
 
 /**
  * Replacement function for realloc(), using huge-page memory. Reserved area
@@ -155,7 +159,8 @@ rte_realloc(void *ptr, size_t size, unsigned int align);
  */
 __rte_experimental
 void *
-rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket);
+rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
+       __rte_alloc_size(2, 3);
 
 /**
  * This function allocates memory from the huge-page area of memory. The memory
@@ -181,7 +186,8 @@ rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket);
  *   - Otherwise, the pointer to the allocated object.
  */
 void *
-rte_malloc_socket(const char *type, size_t size, unsigned align, int socket);
+rte_malloc_socket(const char *type, size_t size, unsigned align, int socket)
+       __rte_alloc_size(2);
 
 /**
  * Allocate zero'ed memory from the heap.
@@ -209,7 +215,8 @@ rte_malloc_socket(const char *type, size_t size, unsigned align, int socket);
  *   - Otherwise, the pointer to the allocated object.
  */
 void *
-rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket);
+rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket)
+       __rte_alloc_size(2);
 
 /**
  * Replacement function for calloc(), using huge-page memory. Memory area is
@@ -237,7 +244,8 @@ rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket);
  *   - Otherwise, the pointer to the allocated object.
  */
 void *
-rte_calloc_socket(const char *type, size_t num, size_t size, unsigned align, int socket);
+rte_calloc_socket(const char *type, size_t num, size_t size, unsigned align, int socket)
+       __rte_alloc_size(2, 3);
 
 /**
  * Frees the memory space pointed to by the provided pointer.