1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 */ 5 6 #define PROTOTYPES 7 8 /* 9 * BGET CONFIGURATION 10 * ================== 11 */ 12 /* #define BGET_ENABLE_ALL_OPTIONS */ 13 #ifdef BGET_ENABLE_OPTION 14 #define TestProg 20000 /* Generate built-in test program 15 if defined. The value specifies 16 how many buffer allocation attempts 17 the test program should make. */ 18 #endif 19 20 21 #ifdef __LP64__ 22 #define SizeQuant 16 23 #endif 24 #ifdef __ILP32__ 25 #define SizeQuant 8 26 #endif 27 /* Buffer allocation size quantum: 28 all buffers allocated are a 29 multiple of this size. This 30 MUST be a power of two. */ 31 32 #ifdef BGET_ENABLE_OPTION 33 #define BufDump 1 /* Define this symbol to enable the 34 bpoold() function which dumps the 35 buffers in a buffer pool. */ 36 37 #define BufValid 1 /* Define this symbol to enable the 38 bpoolv() function for validating 39 a buffer pool. */ 40 41 #define DumpData 1 /* Define this symbol to enable the 42 bufdump() function which allows 43 dumping the contents of an allocated 44 or free buffer. */ 45 46 #define BufStats 1 /* Define this symbol to enable the 47 bstats() function which calculates 48 the total free space in the buffer 49 pool, the largest available 50 buffer, and the total space 51 currently allocated. */ 52 53 #define FreeWipe 1 /* Wipe free buffers to a guaranteed 54 pattern of garbage to trip up 55 miscreants who attempt to use 56 pointers into released buffers. */ 57 58 #define BestFit 1 /* Use a best fit algorithm when 59 searching for space for an 60 allocation request. This uses 61 memory more efficiently, but 62 allocation will be much slower. */ 63 64 #define BECtl 1 /* Define this symbol to enable the 65 bectl() function for automatic 66 pool space control. */ 67 #endif 68 69 #ifdef MEM_DEBUG 70 #undef NDEBUG 71 #define DumpData 1 72 #define BufValid 1 73 #define FreeWipe 1 74 #endif 75 76 #ifdef CFG_WITH_STATS 77 #define BufStats 1 78 #endif 79 80 #include <compiler.h> 81 #include <malloc.h> 82 #include <stdbool.h> 83 #include <stdint.h> 84 #include <stdlib.h> 85 #include <string.h> 86 #include <trace.h> 87 #include <util.h> 88 89 #if defined(__KERNEL__) 90 /* Compiling for TEE Core */ 91 #include <kernel/asan.h> 92 #include <kernel/thread.h> 93 #include <kernel/spinlock.h> 94 95 static void tag_asan_free(void *buf, size_t len) 96 { 97 asan_tag_heap_free(buf, (uint8_t *)buf + len); 98 } 99 100 static void tag_asan_alloced(void *buf, size_t len) 101 { 102 asan_tag_access(buf, (uint8_t *)buf + len); 103 } 104 105 static void *memset_unchecked(void *s, int c, size_t n) 106 { 107 return asan_memset_unchecked(s, c, n); 108 } 109 110 #else /*__KERNEL__*/ 111 /* Compiling for TA */ 112 113 static void tag_asan_free(void *buf __unused, size_t len __unused) 114 { 115 } 116 117 static void tag_asan_alloced(void *buf __unused, size_t len __unused) 118 { 119 } 120 121 static void *memset_unchecked(void *s, int c, size_t n) 122 { 123 return memset(s, c, n); 124 } 125 126 #endif /*__KERNEL__*/ 127 128 #include "bget.c" /* this is ugly, but this is bget */ 129 130 struct malloc_pool { 131 void *buf; 132 size_t len; 133 }; 134 135 struct malloc_ctx { 136 struct bpoolset poolset; 137 struct malloc_pool *pool; 138 size_t pool_len; 139 #ifdef BufStats 140 struct malloc_stats mstats; 141 #endif 142 #ifdef __KERNEL__ 143 unsigned int spinlock; 144 #endif 145 }; 146 147 #ifdef __KERNEL__ 148 149 static uint32_t malloc_lock(struct malloc_ctx *ctx) 150 { 151 return cpu_spin_lock_xsave(&ctx->spinlock); 152 } 153 154 static void malloc_unlock(struct malloc_ctx *ctx, uint32_t exceptions) 155 { 156 cpu_spin_unlock_xrestore(&ctx->spinlock, exceptions); 157 } 158 159 #else /* __KERNEL__ */ 160 161 static uint32_t malloc_lock(struct malloc_ctx *ctx __unused) 162 { 163 return 0; 164 } 165 166 static void malloc_unlock(struct malloc_ctx *ctx __unused, 167 uint32_t exceptions __unused) 168 { 169 } 170 171 #endif /* __KERNEL__ */ 172 173 #define DEFINE_CTX(name) struct malloc_ctx name = \ 174 { .poolset = { .freelist = { {0, 0}, \ 175 {&name.poolset.freelist, \ 176 &name.poolset.freelist}}}} 177 178 static DEFINE_CTX(malloc_ctx); 179 180 #ifdef CFG_VIRTUALIZATION 181 static __nex_data DEFINE_CTX(nex_malloc_ctx); 182 #endif 183 184 #ifdef BufStats 185 186 static void raw_malloc_return_hook(void *p, size_t requested_size, 187 struct malloc_ctx *ctx) 188 { 189 if (ctx->poolset.totalloc > ctx->mstats.max_allocated) 190 ctx->mstats.max_allocated = ctx->poolset.totalloc; 191 192 if (!p) { 193 ctx->mstats.num_alloc_fail++; 194 if (requested_size > ctx->mstats.biggest_alloc_fail) { 195 ctx->mstats.biggest_alloc_fail = requested_size; 196 ctx->mstats.biggest_alloc_fail_used = 197 ctx->poolset.totalloc; 198 } 199 } 200 } 201 202 static void gen_malloc_reset_stats(struct malloc_ctx *ctx) 203 { 204 uint32_t exceptions = malloc_lock(ctx); 205 206 ctx->mstats.max_allocated = 0; 207 ctx->mstats.num_alloc_fail = 0; 208 ctx->mstats.biggest_alloc_fail = 0; 209 ctx->mstats.biggest_alloc_fail_used = 0; 210 malloc_unlock(ctx, exceptions); 211 } 212 213 void malloc_reset_stats(void) 214 { 215 gen_malloc_reset_stats(&malloc_ctx); 216 } 217 218 static void gen_malloc_get_stats(struct malloc_ctx *ctx, 219 struct malloc_stats *stats) 220 { 221 uint32_t exceptions = malloc_lock(ctx); 222 223 memcpy(stats, &ctx->mstats, sizeof(*stats)); 224 stats->allocated = ctx->poolset.totalloc; 225 malloc_unlock(ctx, exceptions); 226 } 227 228 void malloc_get_stats(struct malloc_stats *stats) 229 { 230 gen_malloc_get_stats(&malloc_ctx, stats); 231 } 232 233 #else /* BufStats */ 234 235 static void raw_malloc_return_hook(void *p __unused, 236 size_t requested_size __unused, 237 struct malloc_ctx *ctx __unused) 238 { 239 } 240 241 #endif /* BufStats */ 242 243 #ifdef BufValid 244 static void raw_malloc_validate_pools(struct malloc_ctx *ctx) 245 { 246 size_t n; 247 248 for (n = 0; n < ctx->pool_len; n++) 249 bpoolv(ctx->pool[n].buf); 250 } 251 #else 252 static void raw_malloc_validate_pools(struct malloc_ctx *ctx __unused) 253 { 254 } 255 #endif 256 257 struct bpool_iterator { 258 struct bfhead *next_buf; 259 size_t pool_idx; 260 }; 261 262 static void bpool_foreach_iterator_init(struct malloc_ctx *ctx, 263 struct bpool_iterator *iterator) 264 { 265 iterator->pool_idx = 0; 266 iterator->next_buf = BFH(ctx->pool[0].buf); 267 } 268 269 static bool bpool_foreach_pool(struct bpool_iterator *iterator, void **buf, 270 size_t *len, bool *isfree) 271 { 272 struct bfhead *b = iterator->next_buf; 273 bufsize bs = b->bh.bsize; 274 275 if (bs == ESent) 276 return false; 277 278 if (bs < 0) { 279 /* Allocated buffer */ 280 bs = -bs; 281 282 *isfree = false; 283 } else { 284 /* Free Buffer */ 285 *isfree = true; 286 287 /* Assert that the free list links are intact */ 288 assert(b->ql.blink->ql.flink == b); 289 assert(b->ql.flink->ql.blink == b); 290 } 291 292 *buf = (uint8_t *)b + sizeof(struct bhead); 293 *len = bs - sizeof(struct bhead); 294 295 iterator->next_buf = BFH((uint8_t *)b + bs); 296 return true; 297 } 298 299 static bool bpool_foreach(struct malloc_ctx *ctx, 300 struct bpool_iterator *iterator, void **buf) 301 { 302 while (true) { 303 size_t len; 304 bool isfree; 305 306 if (bpool_foreach_pool(iterator, buf, &len, &isfree)) { 307 if (isfree) 308 continue; 309 return true; 310 } 311 312 if ((iterator->pool_idx + 1) >= ctx->pool_len) 313 return false; 314 315 iterator->pool_idx++; 316 iterator->next_buf = BFH(ctx->pool[iterator->pool_idx].buf); 317 } 318 } 319 320 /* Convenience macro for looping over all allocated buffers */ 321 #define BPOOL_FOREACH(ctx, iterator, bp) \ 322 for (bpool_foreach_iterator_init((ctx),(iterator)); \ 323 bpool_foreach((ctx),(iterator), (bp));) 324 325 static void *raw_malloc(size_t hdr_size, size_t ftr_size, size_t pl_size, 326 struct malloc_ctx *ctx) 327 { 328 void *ptr = NULL; 329 bufsize s; 330 331 /* 332 * Make sure that malloc has correct alignment of returned buffers. 333 * The assumption is that uintptr_t will be as wide as the largest 334 * required alignment of any type. 335 */ 336 COMPILE_TIME_ASSERT(SizeQuant >= sizeof(uintptr_t)); 337 338 raw_malloc_validate_pools(ctx); 339 340 /* Compute total size */ 341 if (ADD_OVERFLOW(pl_size, hdr_size, &s)) 342 goto out; 343 if (ADD_OVERFLOW(s, ftr_size, &s)) 344 goto out; 345 346 /* BGET doesn't like 0 sized allocations */ 347 if (!s) 348 s++; 349 350 ptr = bget(s, &ctx->poolset); 351 out: 352 raw_malloc_return_hook(ptr, pl_size, ctx); 353 354 return ptr; 355 } 356 357 static void raw_free(void *ptr, struct malloc_ctx *ctx) 358 { 359 raw_malloc_validate_pools(ctx); 360 361 if (ptr) 362 brel(ptr, &ctx->poolset); 363 } 364 365 static void *raw_calloc(size_t hdr_size, size_t ftr_size, size_t pl_nmemb, 366 size_t pl_size, struct malloc_ctx *ctx) 367 { 368 void *ptr = NULL; 369 bufsize s; 370 371 raw_malloc_validate_pools(ctx); 372 373 /* Compute total size */ 374 if (MUL_OVERFLOW(pl_nmemb, pl_size, &s)) 375 goto out; 376 if (ADD_OVERFLOW(s, hdr_size, &s)) 377 goto out; 378 if (ADD_OVERFLOW(s, ftr_size, &s)) 379 goto out; 380 381 /* BGET doesn't like 0 sized allocations */ 382 if (!s) 383 s++; 384 385 ptr = bgetz(s, &ctx->poolset); 386 out: 387 raw_malloc_return_hook(ptr, pl_nmemb * pl_size, ctx); 388 389 return ptr; 390 } 391 392 static void *raw_realloc(void *ptr, size_t hdr_size, size_t ftr_size, 393 size_t pl_size, struct malloc_ctx *ctx) 394 { 395 void *p = NULL; 396 bufsize s; 397 398 /* Compute total size */ 399 if (ADD_OVERFLOW(pl_size, hdr_size, &s)) 400 goto out; 401 if (ADD_OVERFLOW(s, ftr_size, &s)) 402 goto out; 403 404 raw_malloc_validate_pools(ctx); 405 406 /* BGET doesn't like 0 sized allocations */ 407 if (!s) 408 s++; 409 410 p = bgetr(ptr, s, &ctx->poolset); 411 out: 412 raw_malloc_return_hook(p, pl_size, ctx); 413 414 return p; 415 } 416 417 /* Most of the stuff in this function is copied from bgetr() in bget.c */ 418 static __maybe_unused bufsize bget_buf_size(void *buf) 419 { 420 bufsize osize; /* Old size of buffer */ 421 struct bhead *b; 422 423 b = BH(((char *)buf) - sizeof(struct bhead)); 424 osize = -b->bsize; 425 #ifdef BECtl 426 if (osize == 0) { 427 /* Buffer acquired directly through acqfcn. */ 428 struct bdhead *bd; 429 430 bd = BDH(((char *)buf) - sizeof(struct bdhead)); 431 osize = bd->tsize - sizeof(struct bdhead); 432 } else 433 #endif 434 osize -= sizeof(struct bhead); 435 assert(osize > 0); 436 return osize; 437 } 438 439 #ifdef ENABLE_MDBG 440 441 struct mdbg_hdr { 442 const char *fname; 443 uint16_t line; 444 uint32_t pl_size; 445 uint32_t magic; 446 #if defined(ARM64) 447 uint64_t pad; 448 #endif 449 }; 450 451 #define MDBG_HEADER_MAGIC 0xadadadad 452 #define MDBG_FOOTER_MAGIC 0xecececec 453 454 static size_t mdbg_get_ftr_size(size_t pl_size) 455 { 456 size_t ftr_pad = ROUNDUP(pl_size, sizeof(uint32_t)) - pl_size; 457 458 return ftr_pad + sizeof(uint32_t); 459 } 460 461 static uint32_t *mdbg_get_footer(struct mdbg_hdr *hdr) 462 { 463 uint32_t *footer; 464 465 footer = (uint32_t *)((uint8_t *)(hdr + 1) + hdr->pl_size + 466 mdbg_get_ftr_size(hdr->pl_size)); 467 footer--; 468 return footer; 469 } 470 471 static void mdbg_update_hdr(struct mdbg_hdr *hdr, const char *fname, 472 int lineno, size_t pl_size) 473 { 474 uint32_t *footer; 475 476 hdr->fname = fname; 477 hdr->line = lineno; 478 hdr->pl_size = pl_size; 479 hdr->magic = MDBG_HEADER_MAGIC; 480 481 footer = mdbg_get_footer(hdr); 482 *footer = MDBG_FOOTER_MAGIC; 483 } 484 485 static void *gen_mdbg_malloc(struct malloc_ctx *ctx, const char *fname, 486 int lineno, size_t size) 487 { 488 struct mdbg_hdr *hdr; 489 uint32_t exceptions = malloc_lock(ctx); 490 491 /* 492 * Check struct mdbg_hdr doesn't get bad alignment. 493 * This is required by C standard: the buffer returned from 494 * malloc() should be aligned with a fundamental alignment. 495 * For ARM32, the required alignment is 8. For ARM64, it is 16. 496 */ 497 COMPILE_TIME_ASSERT( 498 (sizeof(struct mdbg_hdr) % (__alignof(uintptr_t) * 2)) == 0); 499 500 hdr = raw_malloc(sizeof(struct mdbg_hdr), 501 mdbg_get_ftr_size(size), size, ctx); 502 if (hdr) { 503 mdbg_update_hdr(hdr, fname, lineno, size); 504 hdr++; 505 } 506 507 malloc_unlock(ctx, exceptions); 508 return hdr; 509 } 510 511 static void assert_header(struct mdbg_hdr *hdr __maybe_unused) 512 { 513 assert(hdr->magic == MDBG_HEADER_MAGIC); 514 assert(*mdbg_get_footer(hdr) == MDBG_FOOTER_MAGIC); 515 } 516 517 static void gen_mdbg_free(struct malloc_ctx *ctx, void *ptr) 518 { 519 struct mdbg_hdr *hdr = ptr; 520 521 if (hdr) { 522 hdr--; 523 assert_header(hdr); 524 hdr->magic = 0; 525 *mdbg_get_footer(hdr) = 0; 526 raw_free(hdr, ctx); 527 } 528 } 529 530 void free(void *ptr) 531 { 532 uint32_t exceptions = malloc_lock(&malloc_ctx); 533 534 gen_mdbg_free(&malloc_ctx, ptr); 535 malloc_unlock(&malloc_ctx, exceptions); 536 } 537 538 static void *gen_mdbg_calloc(struct malloc_ctx *ctx, const char *fname, int lineno, 539 size_t nmemb, size_t size) 540 { 541 struct mdbg_hdr *hdr; 542 uint32_t exceptions = malloc_lock(ctx); 543 544 hdr = raw_calloc(sizeof(struct mdbg_hdr), 545 mdbg_get_ftr_size(nmemb * size), nmemb, size, 546 ctx); 547 if (hdr) { 548 mdbg_update_hdr(hdr, fname, lineno, nmemb * size); 549 hdr++; 550 } 551 malloc_unlock(ctx, exceptions); 552 return hdr; 553 } 554 555 static void *gen_mdbg_realloc_unlocked(struct malloc_ctx *ctx, const char *fname, 556 int lineno, void *ptr, size_t size) 557 { 558 struct mdbg_hdr *hdr = ptr; 559 560 if (hdr) { 561 hdr--; 562 assert_header(hdr); 563 } 564 hdr = raw_realloc(hdr, sizeof(struct mdbg_hdr), 565 mdbg_get_ftr_size(size), size, ctx); 566 if (hdr) { 567 mdbg_update_hdr(hdr, fname, lineno, size); 568 hdr++; 569 } 570 return hdr; 571 } 572 573 static void *gen_mdbg_realloc(struct malloc_ctx *ctx, const char *fname, 574 int lineno, void *ptr, size_t size) 575 { 576 void *p; 577 uint32_t exceptions = malloc_lock(ctx); 578 579 p = gen_mdbg_realloc_unlocked(ctx, fname, lineno, ptr, size); 580 malloc_unlock(ctx, exceptions); 581 return p; 582 } 583 584 #define realloc_unlocked(ctx, ptr, size) \ 585 gen_mdbg_realloc_unlocked(ctx, __FILE__, __LINE__, (ptr), (size)) 586 587 static void *get_payload_start_size(void *raw_buf, size_t *size) 588 { 589 struct mdbg_hdr *hdr = raw_buf; 590 591 assert(bget_buf_size(hdr) >= hdr->pl_size); 592 *size = hdr->pl_size; 593 return hdr + 1; 594 } 595 596 static void gen_mdbg_check(struct malloc_ctx *ctx, int bufdump) 597 { 598 struct bpool_iterator itr; 599 void *b; 600 uint32_t exceptions = malloc_lock(ctx); 601 602 raw_malloc_validate_pools(ctx); 603 604 BPOOL_FOREACH(ctx, &itr, &b) { 605 struct mdbg_hdr *hdr = (struct mdbg_hdr *)b; 606 607 assert_header(hdr); 608 609 if (bufdump > 0) { 610 const char *fname = hdr->fname; 611 612 if (!fname) 613 fname = "unknown"; 614 615 IMSG("buffer: %d bytes %s:%d\n", 616 hdr->pl_size, fname, hdr->line); 617 } 618 } 619 620 malloc_unlock(ctx, exceptions); 621 } 622 623 void *mdbg_malloc(const char *fname, int lineno, size_t size) 624 { 625 return gen_mdbg_malloc(&malloc_ctx, fname, lineno, size); 626 } 627 628 void *mdbg_calloc(const char *fname, int lineno, size_t nmemb, size_t size) 629 { 630 return gen_mdbg_calloc(&malloc_ctx, fname, lineno, nmemb, size); 631 } 632 633 void *mdbg_realloc(const char *fname, int lineno, void *ptr, size_t size) 634 { 635 return gen_mdbg_realloc(&malloc_ctx, fname, lineno, ptr, size); 636 } 637 638 void mdbg_check(int bufdump) 639 { 640 gen_mdbg_check(&malloc_ctx, bufdump); 641 } 642 #else 643 644 void *malloc(size_t size) 645 { 646 void *p; 647 uint32_t exceptions = malloc_lock(&malloc_ctx); 648 649 p = raw_malloc(0, 0, size, &malloc_ctx); 650 malloc_unlock(&malloc_ctx, exceptions); 651 return p; 652 } 653 654 void free(void *ptr) 655 { 656 uint32_t exceptions = malloc_lock(&malloc_ctx); 657 658 raw_free(ptr, &malloc_ctx); 659 malloc_unlock(&malloc_ctx, exceptions); 660 } 661 662 void *calloc(size_t nmemb, size_t size) 663 { 664 void *p; 665 uint32_t exceptions = malloc_lock(&malloc_ctx); 666 667 p = raw_calloc(0, 0, nmemb, size, &malloc_ctx); 668 malloc_unlock(&malloc_ctx, exceptions); 669 return p; 670 } 671 672 static void *realloc_unlocked(struct malloc_ctx *ctx, void *ptr, 673 size_t size) 674 { 675 return raw_realloc(ptr, 0, 0, size, ctx); 676 } 677 678 void *realloc(void *ptr, size_t size) 679 { 680 void *p; 681 uint32_t exceptions = malloc_lock(&malloc_ctx); 682 683 p = realloc_unlocked(&malloc_ctx, ptr, size); 684 malloc_unlock(&malloc_ctx, exceptions); 685 return p; 686 } 687 688 static void *get_payload_start_size(void *ptr, size_t *size) 689 { 690 *size = bget_buf_size(ptr); 691 return ptr; 692 } 693 694 #endif 695 696 static void gen_malloc_add_pool(struct malloc_ctx *ctx, void *buf, size_t len) 697 { 698 void *p; 699 size_t l; 700 uint32_t exceptions; 701 uintptr_t start = (uintptr_t)buf; 702 uintptr_t end = start + len; 703 const size_t min_len = ((sizeof(struct malloc_pool) + (SizeQuant - 1)) & 704 (~(SizeQuant - 1))) + 705 sizeof(struct bhead) * 2; 706 707 708 start = ROUNDUP(start, SizeQuant); 709 end = ROUNDDOWN(end, SizeQuant); 710 assert(start < end); 711 712 if ((end - start) < min_len) { 713 DMSG("Skipping too small pool"); 714 return; 715 } 716 717 exceptions = malloc_lock(ctx); 718 719 tag_asan_free((void *)start, end - start); 720 bpool((void *)start, end - start, &ctx->poolset); 721 l = ctx->pool_len + 1; 722 p = realloc_unlocked(ctx, ctx->pool, sizeof(struct malloc_pool) * l); 723 assert(p); 724 ctx->pool = p; 725 ctx->pool[ctx->pool_len].buf = (void *)start; 726 ctx->pool[ctx->pool_len].len = end - start; 727 #ifdef BufStats 728 ctx->mstats.size += ctx->pool[ctx->pool_len].len; 729 #endif 730 ctx->pool_len = l; 731 malloc_unlock(ctx, exceptions); 732 } 733 734 static bool gen_malloc_buffer_is_within_alloced(struct malloc_ctx *ctx, 735 void *buf, size_t len) 736 { 737 struct bpool_iterator itr; 738 void *b; 739 uint8_t *start_buf = buf; 740 uint8_t *end_buf = start_buf + len; 741 bool ret = false; 742 uint32_t exceptions = malloc_lock(ctx); 743 744 raw_malloc_validate_pools(ctx); 745 746 /* Check for wrapping */ 747 if (start_buf > end_buf) 748 goto out; 749 750 BPOOL_FOREACH(ctx, &itr, &b) { 751 uint8_t *start_b; 752 uint8_t *end_b; 753 size_t s; 754 755 start_b = get_payload_start_size(b, &s); 756 end_b = start_b + s; 757 758 if (start_buf >= start_b && end_buf <= end_b) { 759 ret = true; 760 goto out; 761 } 762 } 763 764 out: 765 malloc_unlock(ctx, exceptions); 766 767 return ret; 768 } 769 770 static bool gen_malloc_buffer_overlaps_heap(struct malloc_ctx *ctx, 771 void *buf, size_t len) 772 { 773 uintptr_t buf_start = (uintptr_t) buf; 774 uintptr_t buf_end = buf_start + len; 775 size_t n; 776 bool ret = false; 777 uint32_t exceptions = malloc_lock(ctx); 778 779 raw_malloc_validate_pools(ctx); 780 781 for (n = 0; n < ctx->pool_len; n++) { 782 uintptr_t pool_start = (uintptr_t)ctx->pool[n].buf; 783 uintptr_t pool_end = pool_start + ctx->pool[n].len; 784 785 if (buf_start > buf_end || pool_start > pool_end) { 786 ret = true; /* Wrapping buffers, shouldn't happen */ 787 goto out; 788 } 789 790 if (buf_end > pool_start || buf_start < pool_end) { 791 ret = true; 792 goto out; 793 } 794 } 795 796 out: 797 malloc_unlock(ctx, exceptions); 798 return ret; 799 } 800 801 void malloc_add_pool(void *buf, size_t len) 802 { 803 gen_malloc_add_pool(&malloc_ctx, buf, len); 804 } 805 806 bool malloc_buffer_is_within_alloced(void *buf, size_t len) 807 { 808 return gen_malloc_buffer_is_within_alloced(&malloc_ctx, buf, len); 809 } 810 811 bool malloc_buffer_overlaps_heap(void *buf, size_t len) 812 { 813 return gen_malloc_buffer_overlaps_heap(&malloc_ctx, buf, len); 814 } 815 816 #ifdef CFG_VIRTUALIZATION 817 818 #ifndef ENABLE_MDBG 819 820 void *nex_malloc(size_t size) 821 { 822 void *p; 823 uint32_t exceptions = malloc_lock(&nex_malloc_ctx); 824 825 p = raw_malloc(0, 0, size, &nex_malloc_ctx); 826 malloc_unlock(&nex_malloc_ctx, exceptions); 827 return p; 828 } 829 830 void *nex_calloc(size_t nmemb, size_t size) 831 { 832 void *p; 833 uint32_t exceptions = malloc_lock(&nex_malloc_ctx); 834 835 p = raw_calloc(0, 0, nmemb, size, &nex_malloc_ctx); 836 malloc_unlock(&nex_malloc_ctx, exceptions); 837 return p; 838 } 839 840 void *nex_realloc(void *ptr, size_t size) 841 { 842 void *p; 843 uint32_t exceptions = malloc_lock(&nex_malloc_ctx); 844 845 p = realloc_unlocked(&nex_malloc_ctx, ptr, size); 846 malloc_unlock(&nex_malloc_ctx, exceptions); 847 return p; 848 } 849 850 void nex_free(void *ptr) 851 { 852 uint32_t exceptions = malloc_lock(&nex_malloc_ctx); 853 854 raw_free(ptr, &nex_malloc_ctx); 855 malloc_unlock(&nex_malloc_ctx, exceptions); 856 } 857 858 #else /* ENABLE_MDBG */ 859 860 void *nex_mdbg_malloc(const char *fname, int lineno, size_t size) 861 { 862 return gen_mdbg_malloc(&nex_malloc_ctx, fname, lineno, size); 863 } 864 865 void *nex_mdbg_calloc(const char *fname, int lineno, size_t nmemb, size_t size) 866 { 867 return gen_mdbg_calloc(&nex_malloc_ctx, fname, lineno, nmemb, size); 868 } 869 870 void *nex_mdbg_realloc(const char *fname, int lineno, void *ptr, size_t size) 871 { 872 return gen_mdbg_realloc(&nex_malloc_ctx, fname, lineno, ptr, size); 873 } 874 875 void nex_mdbg_check(int bufdump) 876 { 877 gen_mdbg_check(&nex_malloc_ctx, bufdump); 878 } 879 880 void nex_free(void *ptr) 881 { 882 uint32_t exceptions = malloc_lock(&nex_malloc_ctx); 883 884 gen_mdbg_free(&nex_malloc_ctx, ptr); 885 malloc_unlock(&nex_malloc_ctx, exceptions); 886 } 887 888 #endif /* ENABLE_MDBG */ 889 890 void nex_malloc_add_pool(void *buf, size_t len) 891 { 892 gen_malloc_add_pool(&nex_malloc_ctx, buf, len); 893 } 894 895 bool nex_malloc_buffer_is_within_alloced(void *buf, size_t len) 896 { 897 return gen_malloc_buffer_is_within_alloced(&nex_malloc_ctx, buf, len); 898 } 899 900 bool nex_malloc_buffer_overlaps_heap(void *buf, size_t len) 901 { 902 return gen_malloc_buffer_overlaps_heap(&nex_malloc_ctx, buf, len); 903 } 904 905 #ifdef BufStats 906 907 void nex_malloc_reset_stats(void) 908 { 909 gen_malloc_reset_stats(&nex_malloc_ctx); 910 } 911 912 void nex_malloc_get_stats(struct malloc_stats *stats) 913 { 914 gen_malloc_get_stats(&nex_malloc_ctx, stats); 915 } 916 917 #endif 918 919 #endif 920