diff options
Diffstat (limited to 'cpukit/libdl/rtl-allocator.c')
-rw-r--r-- | cpukit/libdl/rtl-allocator.c | 167 |
1 files changed, 140 insertions, 27 deletions
diff --git a/cpukit/libdl/rtl-allocator.c b/cpukit/libdl/rtl-allocator.c index 647c0c89a4..7503183367 100644 --- a/cpukit/libdl/rtl-allocator.c +++ b/cpukit/libdl/rtl-allocator.c @@ -1,10 +1,5 @@ -/* - * COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ +/* SPDX-License-Identifier: BSD-2-Clause */ + /** * @file * @@ -13,6 +8,31 @@ * @brief RTEMS Run-Time Linker Allocator */ +/* + * COPYRIGHT (c) 2012, 2018, 2023 Chris Johns <chrisj@rtems.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + #include <stdio.h> #include <string.h> @@ -90,6 +110,39 @@ rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address) rtems_rtl_unlock (); } +void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag, + void* address, + size_t size, + bool zero) +{ + rtems_rtl_data* rtl = rtems_rtl_lock (); + const void* prev_address = address; + + /* + * Resize memory of an existing allocation. The address field is set + * by the allocator and may change. + */ + if (rtl != NULL) + rtl->allocator.allocator (RTEMS_RTL_ALLOC_RESIZE, tag, &address, size); + + rtems_rtl_unlock (); + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR)) + printf ("rtl: alloc: resize: %s%s prev-addr=%p addr=%p size=%zu\n", + rtems_rtl_trace_tag_label (tag), prev_address == address ? "" : " MOVED", + prev_address, address, size); + + /* + * Only zero the memory if asked to and the resize was successful. We + * cannot clear the resized area if bigger than the previouis allocation + * because we do not have the original size. + */ + if (address != NULL && zero) + memset (address, 0, size); + + return address; +} + void rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address) { @@ -257,21 +310,23 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size, { *text_base = *const_base = *data_base = *bss_base = NULL; - if (text_size) + if (data_size != 0) { - *text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (), - text_size, false); - if (!*text_base) + *data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (), + data_size, false); + if (*data_base == NULL) { + rtems_rtl_alloc_module_del (text_base, const_base, eh_base, + data_base, bss_base); return false; } } - if (const_size) + if (bss_size != 0) { - *const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (), - const_size, false); - if (!*const_base) + *bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (), + bss_size, false); + if (*bss_base == NULL) { rtems_rtl_alloc_module_del (text_base, const_base, eh_base, data_base, bss_base); @@ -279,11 +334,11 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size, } } - if (eh_size) + if (eh_size != 0) { *eh_base = rtems_rtl_alloc_new (rtems_rtl_alloc_eh_tag (), eh_size, false); - if (!*eh_base) + if (*eh_base == NULL) { rtems_rtl_alloc_module_del (text_base, const_base, eh_base, data_base, bss_base); @@ -291,11 +346,11 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size, } } - if (data_size) + if (const_size != 0) { - *data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (), - data_size, false); - if (!*data_base) + *const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (), + const_size, false); + if (*const_base == NULL) { rtems_rtl_alloc_module_del (text_base, const_base, eh_base, data_base, bss_base); @@ -303,14 +358,72 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size, } } - if (bss_size) + if (text_size != 0) { - *bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (), - bss_size, false); - if (!*bss_base) + *text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (), + text_size, false); + if (*text_base == NULL) + { + return false; + } + } + + return true; +} + +bool +rtems_rtl_alloc_module_resize (void** text_base, size_t text_size, + void** const_base, size_t const_size, + void** eh_base, size_t eh_size, + void** data_base, size_t data_size, + void** bss_base, size_t bss_size) +{ + if (data_size != 0) + { + *data_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_data_tag (), + *data_base, data_size, false); + if (*data_base == NULL) + { + return false; + } + } + + if (bss_size != 0) + { + *bss_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_bss_tag (), + *bss_base, bss_size, false); + if (*bss_base == NULL) + { + return false; + } + } + + if (eh_size != 0) + { + *eh_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_eh_tag (), + *eh_base, eh_size, false); + if (*eh_base == NULL) + { + return false; + } + } + + if (const_size != 0) + { + *const_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_const_tag (), + *const_base, const_size, false); + if (*const_base == NULL) + { + return false; + } + } + + if (text_size != 0) + { + *text_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_text_tag (), + *text_base, text_size, false); + if (*text_base == NULL) { - rtems_rtl_alloc_module_del (text_base, const_base, eh_base, - data_base, bss_base); return false; } } |