diff options
Diffstat (limited to '')
-rw-r--r-- | cpukit/libdl/rtl-allocator.c | 135 |
1 files changed, 114 insertions, 21 deletions
diff --git a/cpukit/libdl/rtl-allocator.c b/cpukit/libdl/rtl-allocator.c index f09690d71a..7503183367 100644 --- a/cpukit/libdl/rtl-allocator.c +++ b/cpukit/libdl/rtl-allocator.c @@ -9,7 +9,7 @@ */ /* - * COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org> + * 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 @@ -110,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) { @@ -277,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); @@ -299,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); @@ -311,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); @@ -323,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; } } |