Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
rtx_malloc_wrapper.c
00001 /* 00002 * Copyright (c) 2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "cmsis_os2.h" 00019 #include "uvisor-lib/uvisor-lib.h" 00020 00021 #include <stdint.h> 00022 #include <stddef.h> 00023 #include <stdio.h> 00024 #include <reent.h> 00025 00026 /* 00027 * These are the C standard memory functions: 00028 * - void *calloc(size_t nmemb, size_t size); 00029 * - void free(void *ptr); 00030 * - void *malloc(size_t size); 00031 * - void *realloc(void *ptr, size_t size); 00032 */ 00033 00034 /* Use printf with caution inside malloc: printf may allocate memory itself, 00035 so using printf in malloc may lead to recursive calls! */ 00036 #define DPRINTF(...) {}; 00037 00038 extern RtxBoxIndex * const __uvisor_ps; 00039 00040 /** @retval 0 The kernel is not initialized. 00041 * @retval 1 The kernel is initialized.. */ 00042 static int is_kernel_initialized() 00043 { 00044 /* TODO: Bare-bone boxes must not call any RTX2 functions for now. 00045 * Each box should instead provide `heap_lock` and `heap_unlock` functions 00046 * as part of the box context. These would just be empty for boxes without 00047 * the need for heap locking. */ 00048 if (__uvisor_ps->index.box_id_self != 0) { 00049 return 0; 00050 } 00051 00052 static uint8_t kernel_running = 0; 00053 if (kernel_running) { 00054 return 1; 00055 } 00056 if (osKernelGetState() == osKernelRunning) { 00057 kernel_running = 1; 00058 return 1; 00059 } 00060 return 0; 00061 } 00062 00063 static int init_allocator() 00064 { 00065 int ret = 0; 00066 if (__uvisor_ps == NULL) { 00067 #if defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1) 00068 return -1; 00069 #else 00070 extern void secure_malloc_init(void); 00071 secure_malloc_init(); 00072 #endif 00073 } 00074 00075 if ((__uvisor_ps->mutex_id == NULL) && is_kernel_initialized()) { 00076 /* Point the mutex attr to the data. */ 00077 __uvisor_ps->mutex_attr.name = "uvisor_malloc_mutex"; 00078 __uvisor_ps->mutex_attr.attr_bits = 0; /* Non-recursive */ 00079 __uvisor_ps->mutex_attr.cb_mem = &__uvisor_ps->mutex_data; 00080 __uvisor_ps->mutex_attr.cb_size = sizeof(__uvisor_ps->mutex_data); 00081 00082 /* Create mutex if not already done. */ 00083 __uvisor_ps->mutex_id = osMutexNew(&__uvisor_ps->mutex_attr); 00084 /* Mutex failed to be created. */ 00085 if (__uvisor_ps->mutex_id == NULL) { 00086 return -1; 00087 } 00088 } 00089 00090 if (__uvisor_ps->index.active_heap == NULL) { 00091 /* We need to initialize the process heap. */ 00092 if ((void *) __uvisor_ps->index.bss.address_of.heap != NULL) { 00093 /* Lock the mutex during initialization. */ 00094 int kernel_initialized = is_kernel_initialized(); 00095 if (kernel_initialized) { 00096 osMutexAcquire(__uvisor_ps->mutex_id, osWaitForever); 00097 } 00098 /* Initialize the process heap. */ 00099 SecureAllocator allocator = secure_allocator_create_with_pool( 00100 (void *) __uvisor_ps->index.bss.address_of.heap, 00101 __uvisor_ps->index.box_heap_size); 00102 /* Set the allocator. */ 00103 ret = allocator ? 0 : -1; 00104 __uvisor_ps->index.active_heap = allocator; 00105 /* Release the mutex. */ 00106 if (kernel_initialized) { 00107 osMutexRelease(__uvisor_ps->mutex_id); 00108 } 00109 } 00110 else { 00111 DPRINTF("uvisor_allocator: No process heap available!\n"); 00112 ret = -1; 00113 } 00114 } 00115 return ret; 00116 } 00117 00118 typedef enum { 00119 MEMOP_MALLOC, 00120 MEMOP_MEMALIGN, 00121 MEMOP_CALLOC, 00122 MEMOP_REALLOC, 00123 MEMOP_FREE 00124 } MemoryOperation; 00125 00126 00127 static void * memory(MemoryOperation operation, uint32_t * args) 00128 { 00129 /* Buffer the return value. */ 00130 void * ret = NULL; 00131 /* Initialize allocator. */ 00132 if (init_allocator()) { 00133 return NULL; 00134 } 00135 /* Check if we need to aquire the mutex. */ 00136 int mutexed = is_kernel_initialized(); 00137 void * allocator = __uvisor_ps->index.active_heap; 00138 00139 /* Aquire the mutex if required. 00140 * TODO: Mutex use is very coarse here. It may be sufficient to guard 00141 * the `rt_alloc_mem` and `rt_free_mem` functions in `uvisor_allocator.c`. 00142 * However, it is simpler to do it here for now. */ 00143 if (mutexed) { 00144 osMutexAcquire(__uvisor_ps->mutex_id, osWaitForever); 00145 } 00146 /* Perform the required operation. */ 00147 switch(operation) 00148 { 00149 case MEMOP_MALLOC: 00150 ret = secure_malloc(allocator, (size_t) args[0]); 00151 break; 00152 case MEMOP_MEMALIGN: 00153 ret = secure_aligned_alloc(allocator, (size_t) args[0], (size_t) args[1]); 00154 break; 00155 case MEMOP_CALLOC: 00156 ret = secure_calloc(allocator, (size_t) args[0], (size_t) args[1]); 00157 break; 00158 case MEMOP_REALLOC: 00159 ret = secure_realloc(allocator, (void *) args[0], (size_t) args[1]); 00160 break; 00161 case MEMOP_FREE: 00162 secure_free(allocator, (void *) args[0]); 00163 break; 00164 default: 00165 break; 00166 } 00167 /* Release the mutex if required. */ 00168 if (mutexed) { 00169 osMutexRelease(__uvisor_ps->mutex_id); 00170 } 00171 return ret; 00172 } 00173 00174 /* Wrapped memory management functions. */ 00175 #if defined (__GNUC__) 00176 00177 void * __wrap__malloc_r(struct _reent * r, size_t size) { 00178 (void) r; 00179 return memory(MEMOP_MALLOC, (uint32_t *) &size); 00180 } 00181 void * __wrap__memalign_r(struct _reent * r, size_t alignment, size_t bytes) { 00182 (void) r; 00183 uint32_t args[2] = {(uint32_t) alignment, (uint32_t) bytes}; 00184 return memory(MEMOP_MEMALIGN, args); 00185 } 00186 void * __wrap__calloc_r(struct _reent * r, size_t nmemb, size_t size) { 00187 (void) r; 00188 uint32_t args[2] = {(uint32_t) nmemb, (uint32_t) size}; 00189 return memory(MEMOP_CALLOC, args); 00190 } 00191 void * __wrap__realloc_r(struct _reent * r, void * ptr, size_t size) { 00192 (void) r; 00193 uint32_t args[2] = {(uint32_t) ptr, (uint32_t) size}; 00194 return memory(MEMOP_REALLOC, args); 00195 } 00196 void __wrap__free_r(struct _reent * r, void * ptr) { 00197 (void) r; 00198 memory(MEMOP_FREE, (uint32_t *) &ptr); 00199 } 00200 00201 #elif defined (__CC_ARM) 00202 /* TODO: Find out how to do function wrapping for ARMCC. See microlib libc. */ 00203 # warning "Using uVisor allocator is not available for ARMCC. Falling back to default allocator." 00204 #elif defined (__ICCARM__) 00205 /* TODO: Find out how to do function wrapping for IARCC. */ 00206 # warning "Using uVisor allocator is not available for IARCC. Falling back to default allocator." 00207 #endif
Generated on Fri Jul 22 2022 04:53:59 by
 1.7.2
 1.7.2 
    