File indexing completed on 2025-05-11 08:24:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <stdio.h>
0037 #include <string.h>
0038
0039 #include <rtems/rtl/rtl.h>
0040 #include "rtl-alloc-heap.h"
0041 #include <rtems/rtl/rtl-trace.h>
0042
0043
0044
0045
0046 #if RTEMS_RTL_TRACE
0047 static const char* tag_labels[6] =
0048 {
0049 "OBJECT",
0050 "SYMBOL",
0051 "EXTERNAL",
0052 "READ",
0053 "READ_WRITE",
0054 "READ_EXEC",
0055 };
0056 #define rtems_rtl_trace_tag_label(_l) tag_labels[_l]
0057 #else
0058 #define rtems_rtl_trace_tag_label(_l) ""
0059 #endif
0060
0061 void
0062 rtems_rtl_alloc_initialise (rtems_rtl_alloc_data* data)
0063 {
0064 int c;
0065 data->allocator = rtems_rtl_alloc_heap;
0066 for (c = 0; c < RTEMS_RTL_ALLOC_TAGS; ++c)
0067 rtems_chain_initialize_empty (&data->indirects[c]);
0068 }
0069
0070 void*
0071 rtems_rtl_alloc_new (rtems_rtl_alloc_tag tag, size_t size, bool zero)
0072 {
0073 rtems_rtl_data* rtl = rtems_rtl_lock ();
0074 void* address = NULL;
0075
0076
0077
0078
0079
0080 if (rtl != NULL)
0081 rtl->allocator.allocator (RTEMS_RTL_ALLOC_NEW, tag, &address, size);
0082
0083 rtems_rtl_unlock ();
0084
0085 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0086 printf ("rtl: alloc: new: %s addr=%p size=%zu\n",
0087 rtems_rtl_trace_tag_label (tag), address, size);
0088
0089
0090
0091
0092 if (address != NULL && zero)
0093 memset (address, 0, size);
0094
0095 return address;
0096 }
0097
0098 void
0099 rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address)
0100 {
0101 rtems_rtl_data* rtl = rtems_rtl_lock ();
0102
0103 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0104 printf ("rtl: alloc: del: %s addr=%p\n",
0105 rtems_rtl_trace_tag_label (tag), address);
0106
0107 if (rtl != NULL && address != NULL)
0108 rtl->allocator.allocator (RTEMS_RTL_ALLOC_DEL, tag, &address, 0);
0109
0110 rtems_rtl_unlock ();
0111 }
0112
0113 void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag,
0114 void* address,
0115 size_t size,
0116 bool zero)
0117 {
0118 rtems_rtl_data* rtl = rtems_rtl_lock ();
0119 const void* prev_address = address;
0120
0121
0122
0123
0124
0125 if (rtl != NULL)
0126 rtl->allocator.allocator (RTEMS_RTL_ALLOC_RESIZE, tag, &address, size);
0127
0128 rtems_rtl_unlock ();
0129
0130 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0131 printf ("rtl: alloc: resize: %s%s prev-addr=%p addr=%p size=%zu\n",
0132 rtems_rtl_trace_tag_label (tag), prev_address == address ? "" : " MOVED",
0133 prev_address, address, size);
0134
0135
0136
0137
0138
0139
0140 if (address != NULL && zero)
0141 memset (address, 0, size);
0142
0143 return address;
0144 }
0145
0146 void
0147 rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address)
0148 {
0149 rtems_rtl_data* rtl = rtems_rtl_lock ();
0150
0151 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0152 printf ("rtl: alloc: wr-enable: addr=%p\n", address);
0153
0154 if (rtl != NULL && address != NULL)
0155 rtl->allocator.allocator (RTEMS_RTL_ALLOC_WR_ENABLE,
0156 tag,
0157 address,
0158 0);
0159
0160 rtems_rtl_unlock ();
0161 }
0162
0163 void
0164 rtems_rtl_alloc_lock (void)
0165 {
0166 rtems_rtl_data* rtl = rtems_rtl_lock ();
0167
0168 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0169 printf ("rtl: alloc: lock\n");
0170
0171 if (rtl != NULL)
0172 rtl->allocator.allocator (RTEMS_RTL_ALLOC_LOCK,
0173 RTEMS_RTL_ALLOC_OBJECT,
0174 NULL,
0175 0);
0176
0177 rtems_rtl_unlock ();
0178 }
0179
0180
0181 void
0182 rtems_rtl_alloc_unlock (void)
0183 {
0184 rtems_rtl_data* rtl = rtems_rtl_lock ();
0185
0186 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0187 printf ("rtl: alloc: unlock\n");
0188
0189 if (rtl != NULL)
0190 rtl->allocator.allocator (RTEMS_RTL_ALLOC_UNLOCK,
0191 RTEMS_RTL_ALLOC_OBJECT,
0192 NULL,
0193 0);
0194
0195 rtems_rtl_unlock ();
0196 }
0197 void
0198 rtems_rtl_alloc_wr_disable (rtems_rtl_alloc_tag tag, void* address)
0199 {
0200 rtems_rtl_data* rtl = rtems_rtl_lock ();
0201
0202 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0203 printf ("rtl: alloc: wr-disable: addr=%p\n", address);
0204
0205 if (rtl != NULL && address != NULL)
0206 rtl->allocator.allocator (RTEMS_RTL_ALLOC_WR_DISABLE,
0207 tag,
0208 address,
0209 0);
0210
0211 rtems_rtl_unlock ();
0212 }
0213
0214 rtems_rtl_allocator
0215 rtems_rtl_alloc_hook (rtems_rtl_allocator handler)
0216 {
0217 rtems_rtl_data* rtl = rtems_rtl_lock ();
0218 rtems_rtl_allocator previous = rtl->allocator.allocator;
0219 rtl->allocator.allocator = handler;
0220 rtems_rtl_unlock ();
0221 return previous;
0222 }
0223
0224 void
0225 rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag tag,
0226 rtems_rtl_ptr* handle,
0227 size_t size)
0228 {
0229 rtems_rtl_data* rtl = rtems_rtl_lock ();
0230
0231 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0232 {
0233 if (!rtems_rtl_ptr_null (handle))
0234 printf ("rtl: alloc: inew: %s handle=%p: not null\n",
0235 rtems_rtl_trace_tag_label (tag), handle);
0236 printf ("rtl: alloc: inew: %s handle=%p size=%zd\n",
0237 rtems_rtl_trace_tag_label (tag), handle, size);
0238 }
0239
0240 if (rtl)
0241 {
0242 rtems_rtl_alloc_data* allocator = &rtl->allocator;
0243 handle->pointer = rtems_rtl_alloc_new (tag, size, false);
0244 if (!rtems_rtl_ptr_null (handle))
0245 rtems_chain_append_unprotected (&allocator->indirects[tag],
0246 &handle->node);
0247 }
0248
0249 rtems_rtl_unlock ();
0250 }
0251
0252 void
0253 rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag tag,
0254 rtems_rtl_ptr* handle)
0255 {
0256 rtems_rtl_data* rtl = rtems_rtl_lock ();
0257
0258 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
0259 {
0260 if (rtems_rtl_ptr_null (handle))
0261 printf ("rtl: alloc: idel: %s handle=%p: is null\n",
0262 rtems_rtl_trace_tag_label (tag), handle);
0263 printf ("rtl: alloc: idel: %s handle=%p\n",
0264 rtems_rtl_trace_tag_label (tag), handle);
0265 }
0266
0267 if (rtl && !rtems_rtl_ptr_null (handle))
0268 {
0269 rtems_chain_extract_unprotected (&handle->node);
0270 rtems_rtl_alloc_del (tag, &handle->pointer);
0271 }
0272 }
0273
0274 rtems_rtl_alloc_tag
0275 rtems_rtl_alloc_text_tag (void)
0276 {
0277 return RTEMS_RTL_ALLOC_READ_EXEC;
0278 }
0279
0280 rtems_rtl_alloc_tag
0281 rtems_rtl_alloc_const_tag (void)
0282 {
0283 return RTEMS_RTL_ALLOC_READ;
0284 }
0285
0286 rtems_rtl_alloc_tag
0287 rtems_rtl_alloc_eh_tag (void)
0288 {
0289 return RTEMS_RTL_ALLOC_READ;
0290 }
0291
0292 rtems_rtl_alloc_tag
0293 rtems_rtl_alloc_data_tag (void)
0294 {
0295 return RTEMS_RTL_ALLOC_READ_WRITE;
0296 }
0297
0298 rtems_rtl_alloc_tag
0299 rtems_rtl_alloc_bss_tag (void)
0300 {
0301 return RTEMS_RTL_ALLOC_READ_WRITE;
0302 }
0303
0304 bool
0305 rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
0306 void** const_base, size_t const_size,
0307 void** eh_base, size_t eh_size,
0308 void** data_base, size_t data_size,
0309 void** bss_base, size_t bss_size)
0310 {
0311 *text_base = *const_base = *data_base = *bss_base = NULL;
0312
0313 if (data_size != 0)
0314 {
0315 *data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (),
0316 data_size, false);
0317 if (*data_base == NULL)
0318 {
0319 rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
0320 data_base, bss_base);
0321 return false;
0322 }
0323 }
0324
0325 if (bss_size != 0)
0326 {
0327 *bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (),
0328 bss_size, false);
0329 if (*bss_base == NULL)
0330 {
0331 rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
0332 data_base, bss_base);
0333 return false;
0334 }
0335 }
0336
0337 if (eh_size != 0)
0338 {
0339 *eh_base = rtems_rtl_alloc_new (rtems_rtl_alloc_eh_tag (),
0340 eh_size, false);
0341 if (*eh_base == NULL)
0342 {
0343 rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
0344 data_base, bss_base);
0345 return false;
0346 }
0347 }
0348
0349 if (const_size != 0)
0350 {
0351 *const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (),
0352 const_size, false);
0353 if (*const_base == NULL)
0354 {
0355 rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
0356 data_base, bss_base);
0357 return false;
0358 }
0359 }
0360
0361 if (text_size != 0)
0362 {
0363 *text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (),
0364 text_size, false);
0365 if (*text_base == NULL)
0366 {
0367 return false;
0368 }
0369 }
0370
0371 return true;
0372 }
0373
0374 bool
0375 rtems_rtl_alloc_module_resize (void** text_base, size_t text_size,
0376 void** const_base, size_t const_size,
0377 void** eh_base, size_t eh_size,
0378 void** data_base, size_t data_size,
0379 void** bss_base, size_t bss_size)
0380 {
0381 if (data_size != 0)
0382 {
0383 *data_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_data_tag (),
0384 *data_base, data_size, false);
0385 if (*data_base == NULL)
0386 {
0387 return false;
0388 }
0389 }
0390
0391 if (bss_size != 0)
0392 {
0393 *bss_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_bss_tag (),
0394 *bss_base, bss_size, false);
0395 if (*bss_base == NULL)
0396 {
0397 return false;
0398 }
0399 }
0400
0401 if (eh_size != 0)
0402 {
0403 *eh_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_eh_tag (),
0404 *eh_base, eh_size, false);
0405 if (*eh_base == NULL)
0406 {
0407 return false;
0408 }
0409 }
0410
0411 if (const_size != 0)
0412 {
0413 *const_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_const_tag (),
0414 *const_base, const_size, false);
0415 if (*const_base == NULL)
0416 {
0417 return false;
0418 }
0419 }
0420
0421 if (text_size != 0)
0422 {
0423 *text_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_text_tag (),
0424 *text_base, text_size, false);
0425 if (*text_base == NULL)
0426 {
0427 return false;
0428 }
0429 }
0430
0431 return true;
0432 }
0433
0434 void
0435 rtems_rtl_alloc_module_del (void** text_base,
0436 void** const_base,
0437 void** eh_base,
0438 void** data_base,
0439 void** bss_base)
0440 {
0441 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *bss_base);
0442 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *data_base);
0443 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *eh_base);
0444 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *const_base);
0445 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_EXEC, *text_base);
0446 *text_base = *const_base = *eh_base = *data_base = *bss_base = NULL;
0447 }