blob: 452d74f88879dc4d86de5d4acf6d62ea8f1a49e5 [file] [log] [blame]
Jakub Czapiga7a187212021-02-15 09:54:03 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3/* Include malloc() and memalign() source code and alter its name to indicate the functions
4 source origin. */
Tim Wawrzynczakc556dff2021-03-30 11:49:14 -06005#define calloc cb_calloc
Jakub Czapiga7a187212021-02-15 09:54:03 +01006#define malloc cb_malloc
7#define free cb_free
8#define memalign cb_memalign
9#undef __noreturn
10#define __noreturn
11
12#include "../lib/malloc.c"
13
Tim Wawrzynczakc556dff2021-03-30 11:49:14 -060014#undef calloc
Jakub Czapiga7a187212021-02-15 09:54:03 +010015#undef malloc
16#undef free
17#undef memalign
18#undef __noreturn
19#define __noreturn __attribute__((noreturn))
20
21#include <stdlib.h>
22#include <tests/test.h>
23#include <commonlib/helpers.h>
24#include <types.h>
25#include <symbols.h>
26
27/* 4 MiB */
28#define TEST_HEAP_SZ 0x400000
29
30/* Heap region setup */
31__weak extern uint8_t _test_heap[];
32__weak extern uint8_t _etest_heap[];
33TEST_REGION(test_heap, TEST_HEAP_SZ);
34TEST_SYMBOL(_heap, _test_heap);
35TEST_SYMBOL(_eheap, _etest_heap);
36
37void die(const char *msg, ...)
38{
39 function_called();
40}
41
42static int setup_test(void **state)
43{
44 free_mem_ptr = &_heap;
45 free_mem_end_ptr = &_eheap;
46 free_last_alloc_ptr = &_heap;
47
48 return 0;
49}
50
Tim Wawrzynczakc556dff2021-03-30 11:49:14 -060051static int setup_calloc_test(void **state)
52{
Jakub Czapiga13145e52021-04-06 18:27:30 +020053 memset(_test_heap, 0xFF, TEST_HEAP_SZ);
Tim Wawrzynczakc556dff2021-03-30 11:49:14 -060054 return setup_test(state);
55}
56
Jakub Czapiga7a187212021-02-15 09:54:03 +010057static void test_malloc_out_of_memory(void **state)
58{
59 /* Expect die() call if out of memory */
60 expect_function_call(die);
61 cb_malloc(TEST_HEAP_SZ);
62}
63
64static void test_malloc_zero(void **state)
65{
66 void *ptr1 = cb_malloc(0);
67 void *ptr2 = cb_malloc(0);
68 void *ptr3 = cb_malloc(0);
69
70 /* Expect malloc(0) to return the same pointer as there are no bytes
71 to be added to the heap */
72 assert_ptr_equal(ptr1, ptr2);
73 assert_ptr_equal(ptr2, ptr3);
74}
75
76static void test_malloc_multiple_small_allocations(void **state)
77{
78 /* Make multiple small allocations (smaller than alignment)
79 Expect no call to die(), as this allocations should be small
80 enough to fit in provided memory */
81 void *prev;
82 void *curr = cb_malloc(3);
83 assert_non_null(curr);
84 for (int i = 0; i < 1000; ++i) {
85 prev = curr;
86 curr = cb_malloc(3);
87 assert_non_null(curr);
88 assert_true(prev < curr);
89 }
90}
91
92static void test_memalign_different_alignments(void **state)
93{
94 void *ptr1 = cb_memalign(4, 30);
95 void *ptr2 = cb_memalign(16, 22);
96 void *ptr3 = cb_memalign(8, 64);
97
98 assert_true((uintptr_t)ptr1 % 4 == 0);
99 assert_true((uintptr_t)ptr2 % 16 == 0);
100 assert_true((uintptr_t)ptr3 % 8 == 0);
101}
102
103static void test_memalign_out_of_memory(void **state)
104{
105 expect_function_call(die);
106 cb_memalign(16, TEST_HEAP_SZ);
107}
108
109static void test_memalign_zero(void **state)
110{
111 void *ptr1 = cb_memalign(16, 0);
112 void *ptr2 = cb_memalign(7, 0);
113 void *ptr3 = cb_memalign(11, 0);
114
115 /* Expect memalign(x, 0) to return the same pointer as there are no bytes
116 to be added to the heap */
117 assert_ptr_equal(ptr1, ptr2);
118 assert_ptr_equal(ptr2, ptr3);
119}
120
121static void test_memalign_multiple_small_allocations(void **state)
122{
123 /* Make multiple small allocations (smaller than alignment)
124 Expect no call to die(), as this allocations should be small
125 enough to fit in provided memory. There should also be no error
126 when allocating memory with different align values. */
127 void *prev;
128 void *curr = cb_memalign(3, 3);
129 assert_non_null(curr);
130 for (int i = 0; i < 1000; ++i) {
131 /* Expect new pointer larger than previously allocated and aligned to provided
132 value. Alignment has to be power of 2 to be applied correctly. */
133 prev = curr;
134 curr = cb_memalign(2u << (i % 6), 3);
135 assert_non_null(curr);
136 assert_true(prev < curr);
137 assert_true((uintptr_t)curr % (2u << (i % 6)) == 0);
138 }
139}
140
Tim Wawrzynczakc556dff2021-03-30 11:49:14 -0600141static void test_calloc_memory_is_zeroed(void **state)
142{
143 const size_t nitems = 42;
144 const size_t size = sizeof(uint32_t);
145 void *ptr = cb_calloc(nitems, size);
146 assert_non_null(ptr);
147
148 for (size_t i = 0; i < nitems; i++) {
149 const uint32_t *p = (const uint32_t *)ptr + i;
150 assert_int_equal(*p, 0);
151 }
152}
153
Jakub Czapiga7a187212021-02-15 09:54:03 +0100154int main(void)
155{
156 const struct CMUnitTest tests[] = {
157 cmocka_unit_test_setup(test_malloc_out_of_memory, setup_test),
158 cmocka_unit_test_setup(test_malloc_zero, setup_test),
159 cmocka_unit_test_setup(test_malloc_multiple_small_allocations, setup_test),
160 cmocka_unit_test_setup(test_memalign_different_alignments, setup_test),
161 cmocka_unit_test_setup(test_memalign_out_of_memory, setup_test),
162 cmocka_unit_test_setup(test_memalign_zero, setup_test),
163 cmocka_unit_test_setup(test_memalign_multiple_small_allocations, setup_test),
Tim Wawrzynczakc556dff2021-03-30 11:49:14 -0600164 cmocka_unit_test_setup(test_calloc_memory_is_zeroed, setup_calloc_test),
Jakub Czapiga7a187212021-02-15 09:54:03 +0100165 };
166
Jakub Czapiga7c6081e2021-08-25 16:27:35 +0200167 return cb_run_group_tests(tests, NULL, NULL);
Jakub Czapiga7a187212021-02-15 09:54:03 +0100168}