Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 : : /* 3 : : * Copyright 2013-2018 IBM Corp. 4 : : */ 5 : : 6 : : #include <config.h> 7 : : 8 : : #define BITS_PER_LONG (sizeof(long) * 8) 9 : : 10 : : #include "dummy-cpu.h" 11 : : 12 : : #include <stdlib.h> 13 : : 14 : : /* Use these before we undefine them below. */ 15 : 1 : static inline void *real_malloc(size_t size) 16 : : { 17 : 1 : return malloc(size); 18 : : } 19 : : 20 : 1 : static inline void real_free(void *p) 21 : : { 22 : 1 : return free(p); 23 : : } 24 : : 25 : : #undef malloc 26 : : #undef free 27 : : #undef realloc 28 : : 29 : : #include <skiboot.h> 30 : : 31 : : #define is_rodata(p) true 32 : : 33 : : #include "../mem_region.c" 34 : : #include "../malloc.c" 35 : : #include "../device.c" 36 : : 37 : : #include "mem_region-malloc.h" 38 : : 39 : : #define TEST_HEAP_ORDER 16 40 : : #define TEST_HEAP_SIZE (1ULL << TEST_HEAP_ORDER) 41 : : 42 : : struct dt_node *dt_root; 43 : : enum proc_chip_quirks proc_chip_quirks; 44 : : 45 : 58 : void lock_caller(struct lock *l, const char *caller) 46 : : { 47 : : (void)caller; 48 : 58 : assert(!l->lock_val); 49 : 58 : l->lock_val = 1; 50 : 58 : } 51 : : 52 : 58 : void unlock(struct lock *l) 53 : : { 54 : 58 : assert(l->lock_val); 55 : 58 : l->lock_val = 0; 56 : 58 : } 57 : : 58 : 61 : bool lock_held_by_me(struct lock *l) 59 : : { 60 : 61 : return l->lock_val; 61 : : } 62 : : 63 : 21 : static bool heap_empty(void) 64 : : { 65 : 21 : const struct alloc_hdr *h = region_start(&skiboot_heap); 66 : 21 : return h->num_longs == skiboot_heap.len / sizeof(long); 67 : : } 68 : : 69 : 1 : int main(void) 70 : : { 71 : 1 : char *test_heap = real_malloc(TEST_HEAP_SIZE); 72 : : char *p, *p2, *p3, *p4; 73 : : char *pr; 74 : : size_t i; 75 : : 76 : : /* Use malloc for the heap, so valgrind can find issues. */ 77 : 1 : skiboot_heap.start = (unsigned long)test_heap; 78 : 1 : skiboot_heap.len = TEST_HEAP_SIZE; 79 : : 80 : : /* Allocations of various sizes. */ 81 : 17 : for (i = 0; i < TEST_HEAP_ORDER; i++) { 82 : 16 : p = malloc(1ULL << i); 83 : 16 : assert(p); 84 : 16 : assert(p > (char *)test_heap); 85 : 16 : assert(p + (1ULL << i) <= (char *)test_heap + TEST_HEAP_SIZE); 86 : 16 : assert(!skiboot_heap.free_list_lock.lock_val); 87 : 16 : free(p); 88 : 16 : assert(!skiboot_heap.free_list_lock.lock_val); 89 : 16 : assert(heap_empty()); 90 : : } 91 : : 92 : : /* Realloc as malloc. */ 93 : 1 : skiboot_heap.free_list_lock.lock_val = 0; 94 : 1 : p = realloc(NULL, 100); 95 : 1 : assert(p); 96 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 97 : : 98 : : /* Realloc as free. */ 99 : 1 : p = realloc(p, 0); 100 : 1 : assert(!p); 101 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 102 : 1 : assert(heap_empty()); 103 : : 104 : : /* Realloc longer. */ 105 : 1 : p = realloc(NULL, 100); 106 : 1 : assert(p); 107 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 108 : 1 : p2 = realloc(p, 200); 109 : 1 : assert(p2 == p); 110 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 111 : 1 : free(p2); 112 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 113 : 1 : assert(heap_empty()); 114 : : 115 : : /* Realloc shorter. */ 116 : 1 : skiboot_heap.free_list_lock.lock_val = 0; 117 : 1 : p = realloc(NULL, 100); 118 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 119 : 1 : assert(p); 120 : 1 : p2 = realloc(p, 1); 121 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 122 : 1 : assert(p2 == p); 123 : 1 : free(p2); 124 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 125 : 1 : assert(heap_empty()); 126 : : 127 : : /* zalloc failure */ 128 : 1 : p2 = zalloc(TEST_HEAP_SIZE * 2); 129 : 1 : assert(p2 == NULL); 130 : : 131 : : /* Realloc with move. */ 132 : 1 : p2 = malloc(TEST_HEAP_SIZE - 64 - sizeof(struct alloc_hdr)*2); 133 : 1 : memset(p2, 'a', TEST_HEAP_SIZE - 64 - sizeof(struct alloc_hdr)*2); 134 : 1 : assert(p2); 135 : 1 : p = malloc(64); 136 : 1 : memset(p, 'b', 64); 137 : 1 : p[63] = 'c'; 138 : 1 : assert(p); 139 : 1 : free(p2); 140 : : 141 : 1 : p2 = realloc(p, 128); 142 : 1 : assert(p2 != p); 143 : 1 : assert(p2[63] == 'c'); 144 : 1 : free(p2); 145 : 1 : assert(heap_empty()); 146 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 147 : : 148 : : /* Realloc with failure to allocate new size */ 149 : 1 : p2 = malloc(TEST_HEAP_SIZE - sizeof(struct alloc_hdr)*2); 150 : 1 : assert(p2); 151 : 1 : memset(p2, 'a', TEST_HEAP_SIZE - sizeof(struct alloc_hdr)*2); 152 : 1 : p = p2; 153 : 1 : p2 = realloc(p, TEST_HEAP_SIZE*2); 154 : 1 : assert(p2==NULL); 155 : 1 : memset(p, 'b', TEST_HEAP_SIZE - sizeof(struct alloc_hdr)*2); 156 : 1 : free(p); 157 : : 158 : : /* Reproduce bug BZ109128/SW257364 */ 159 : 1 : p = malloc(100); 160 : 1 : p2 = malloc(100); 161 : 1 : p3 = malloc(100); 162 : 1 : p4 = malloc(100); 163 : 1 : free(p2); 164 : 1 : pr = realloc(p,216); 165 : 1 : assert(pr); 166 : 1 : free(p3); 167 : 1 : free(pr); 168 : 1 : free(p4); 169 : 1 : assert(heap_empty()); 170 : 1 : assert(!skiboot_heap.free_list_lock.lock_val); 171 : : 172 : 1 : real_free(test_heap); 173 : 1 : return 0; 174 : : }