1 /* 2 * Copyright (c) 2014, STMicroelectronics International N.V. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #define PROTOTYPES 29 30 /* 31 * BGET CONFIGURATION 32 * ================== 33 */ 34 /* #define BGET_ENABLE_ALL_OPTIONS */ 35 #ifdef BGET_ENABLE_OPTION 36 #define TestProg 20000 /* Generate built-in test program 37 if defined. The value specifies 38 how many buffer allocation attempts 39 the test program should make. */ 40 #endif 41 42 43 #define SizeQuant 8 /* Buffer allocation size quantum: 44 all buffers allocated are a 45 multiple of this size. This 46 MUST be a power of two. */ 47 48 #ifdef BGET_ENABLE_OPTION 49 #define BufDump 1 /* Define this symbol to enable the 50 bpoold() function which dumps the 51 buffers in a buffer pool. */ 52 53 #define BufValid 1 /* Define this symbol to enable the 54 bpoolv() function for validating 55 a buffer pool. */ 56 57 #define DumpData 1 /* Define this symbol to enable the 58 bufdump() function which allows 59 dumping the contents of an allocated 60 or free buffer. */ 61 62 #define BufStats 1 /* Define this symbol to enable the 63 bstats() function which calculates 64 the total free space in the buffer 65 pool, the largest available 66 buffer, and the total space 67 currently allocated. */ 68 69 #define FreeWipe 1 /* Wipe free buffers to a guaranteed 70 pattern of garbage to trip up 71 miscreants who attempt to use 72 pointers into released buffers. */ 73 74 #define BestFit 1 /* Use a best fit algorithm when 75 searching for space for an 76 allocation request. This uses 77 memory more efficiently, but 78 allocation will be much slower. */ 79 80 #define BECtl 1 /* Define this symbol to enable the 81 bectl() function for automatic 82 pool space control. */ 83 #endif 84 85 #ifdef MEM_DEBUG 86 #undef NDEBUG 87 #define DumpData 1 88 #define BufValid 1 89 #define FreeWipe 1 90 #endif 91 92 #if defined(CFG_TEE_CORE_DEBUG) && CFG_TEE_CORE_DEBUG != 0 93 #define BufStats 1 94 #endif 95 96 #include <stdlib.h> 97 #include <stdint.h> 98 #include <stdbool.h> 99 #include <malloc.h> 100 #include "bget.c" /* this is ugly, but this is bget */ 101 #include <util.h> 102 103 struct malloc_pool { 104 void *buf; 105 size_t len; 106 }; 107 108 static struct malloc_pool *malloc_pool; 109 static size_t malloc_pool_len; 110 111 #ifdef BufStats 112 static size_t max_alloc_heap; 113 114 static void raw_malloc_save_max_alloced_size(void) 115 { 116 if (totalloc > max_alloc_heap) 117 max_alloc_heap = totalloc; 118 } 119 120 void malloc_reset_max_allocated(void) 121 { 122 max_alloc_heap = 0; 123 } 124 125 size_t malloc_get_max_allocated(void) 126 { 127 return max_alloc_heap; 128 } 129 130 size_t malloc_get_allocated(void) 131 { 132 return totalloc; 133 } 134 135 #else /* BufStats */ 136 137 static void raw_malloc_save_max_alloced_size(void) 138 { 139 } 140 141 void malloc_reset_max_allocated(void) 142 { 143 } 144 145 size_t malloc_get_max_allocated(void) 146 { 147 return 0; 148 } 149 150 size_t malloc_get_allocated(void) 151 { 152 return 0; 153 } 154 #endif /* BufStats */ 155 156 size_t malloc_get_heap_size(void) 157 { 158 size_t n; 159 size_t s = 0; 160 161 for (n = 0; n < malloc_pool_len; n++) 162 s += malloc_pool[n].len; 163 164 return s; 165 } 166 167 #ifdef BufValid 168 static void raw_malloc_validate_pools(void) 169 { 170 size_t n; 171 172 for (n = 0; n < malloc_pool_len; n++) 173 bpoolv(malloc_pool[n].buf); 174 } 175 #else 176 static void raw_malloc_validate_pools(void) 177 { 178 } 179 #endif 180 181 struct bpool_iterator { 182 struct bfhead *next_buf; 183 size_t pool_idx; 184 }; 185 186 static void bpool_foreach_iterator_init(struct bpool_iterator *iterator) 187 { 188 iterator->pool_idx = 0; 189 iterator->next_buf = BFH(malloc_pool[0].buf); 190 } 191 192 static bool bpool_foreach_pool(struct bpool_iterator *iterator, void **buf, 193 size_t *len, bool *isfree) 194 { 195 struct bfhead *b = iterator->next_buf; 196 bufsize bs = b->bh.bsize; 197 198 if (bs == ESent) 199 return false; 200 201 if (bs < 0) { 202 /* Allocated buffer */ 203 bs = -bs; 204 205 *isfree = false; 206 } else { 207 /* Free Buffer */ 208 *isfree = true; 209 210 /* Assert that the free list links are intact */ 211 assert(b->ql.blink->ql.flink == b); 212 assert(b->ql.flink->ql.blink == b); 213 } 214 215 *buf = (uint8_t *)b + sizeof(struct bhead); 216 *len = bs - sizeof(struct bhead); 217 218 iterator->next_buf = BFH((uint8_t *)b + bs); 219 return true; 220 } 221 222 static bool bpool_foreach(struct bpool_iterator *iterator, void **buf) 223 { 224 while (true) { 225 size_t len; 226 bool isfree; 227 228 if (bpool_foreach_pool(iterator, buf, &len, &isfree)) { 229 if (isfree) 230 continue; 231 return true; 232 } 233 234 if ((iterator->pool_idx + 1) >= malloc_pool_len) 235 return false; 236 237 iterator->pool_idx++; 238 iterator->next_buf = BFH(malloc_pool[iterator->pool_idx].buf); 239 } 240 } 241 242 /* Convenience macro for looping over all allocated buffers */ 243 #define BPOOL_FOREACH(iterator, bp) \ 244 for (bpool_foreach_iterator_init((iterator)); \ 245 bpool_foreach((iterator), (bp));) 246 247 static void *raw_malloc(size_t hdr_size, size_t ftr_size, size_t pl_size) 248 { 249 void *ptr; 250 size_t s = hdr_size + ftr_size + pl_size; 251 252 /* 253 * Make sure that malloc has correct alignment of returned buffers. 254 * The assumption is that uintptr_t will be as wide as the largest 255 * required alignment of any type. 256 */ 257 COMPILE_TIME_ASSERT(SizeQuant >= sizeof(uintptr_t)); 258 259 raw_malloc_validate_pools(); 260 261 /* Check wrapping */ 262 if (s < pl_size) 263 return NULL; 264 265 /* BGET doesn't like 0 sized allocations */ 266 if (!s) 267 s++; 268 269 ptr = bget(s); 270 raw_malloc_save_max_alloced_size(); 271 return ptr; 272 } 273 274 static void raw_free(void *ptr) 275 { 276 raw_malloc_validate_pools(); 277 278 if (ptr) 279 brel(ptr); 280 } 281 282 static void *raw_calloc(size_t hdr_size, size_t ftr_size, size_t pl_nmemb, 283 size_t pl_size) 284 { 285 size_t s = hdr_size + ftr_size + pl_nmemb * pl_size; 286 void *ptr; 287 288 raw_malloc_validate_pools(); 289 290 /* Check wrapping */ 291 if (s < pl_nmemb || s < pl_size) 292 return NULL; 293 294 /* BGET doesn't like 0 sized allocations */ 295 if (!s) 296 s++; 297 298 ptr = bgetz(s); 299 raw_malloc_save_max_alloced_size(); 300 return ptr; 301 } 302 303 static void *raw_realloc(void *ptr, size_t hdr_size, size_t ftr_size, 304 size_t pl_size) 305 { 306 size_t s = hdr_size + ftr_size + pl_size; 307 void *p; 308 309 raw_malloc_validate_pools(); 310 311 /* Check wrapping */ 312 if (s < pl_size) 313 return NULL; 314 315 /* BGET doesn't like 0 sized allocations */ 316 if (!s) 317 s++; 318 319 p = bgetr(ptr, s); 320 raw_malloc_save_max_alloced_size(); 321 return p; 322 } 323 324 static void create_free_block(struct bfhead *bf, bufsize size, struct bhead *bn) 325 { 326 assert(BH((char *)bf + size) == bn); 327 assert(bn->bsize < 0); /* Next block should be allocated */ 328 /* Next block shouldn't already have free block in front */ 329 assert(bn->prevfree == 0); 330 331 /* Create the free buf header */ 332 bf->bh.bsize = size; 333 bf->bh.prevfree = 0; 334 335 /* Update next block to point to the new free buf header */ 336 bn->prevfree = size; 337 338 /* Insert the free buffer on the free list */ 339 assert(freelist.ql.blink->ql.flink == &freelist); 340 assert(freelist.ql.flink->ql.blink == &freelist); 341 bf->ql.flink = &freelist; 342 bf->ql.blink = freelist.ql.blink; 343 freelist.ql.blink = bf; 344 bf->ql.blink->ql.flink = bf; 345 } 346 347 static void brel_before(char *orig_buf, char *new_buf) 348 { 349 struct bfhead *bf; 350 struct bhead *b; 351 bufsize size; 352 bufsize orig_size; 353 354 assert(orig_buf < new_buf); 355 /* There has to be room for the freebuf header */ 356 size = (bufsize)(new_buf - orig_buf); 357 assert(size >= (SizeQ + sizeof(struct bhead))); 358 359 /* Point to head of original buffer */ 360 bf = BFH(orig_buf - sizeof(struct bhead)); 361 orig_size = -bf->bh.bsize; /* negative since it's an allocated buffer */ 362 363 /* Point to head of the becoming new allocated buffer */ 364 b = BH(new_buf - sizeof(struct bhead)); 365 366 if (bf->bh.prevfree != 0) { 367 /* Previous buffer is free, consolidate with that buffer */ 368 struct bfhead *bfp; 369 370 /* Update the previous free buffer */ 371 bfp = BFH((char *)bf - bf->bh.prevfree); 372 assert(bfp->bh.bsize == bf->bh.prevfree); 373 bfp->bh.bsize += size; 374 375 /* Make a new allocated buffer header */ 376 b->prevfree = bfp->bh.bsize; 377 /* Make it negative since it's an allocated buffer */ 378 b->bsize = -(orig_size - size); 379 } else { 380 /* 381 * Previous buffer is allocated, create a new buffer and 382 * insert on the free list. 383 */ 384 385 /* Make it negative since it's an allocated buffer */ 386 b->bsize = -(orig_size - size); 387 388 create_free_block(bf, size, b); 389 } 390 391 #ifdef BufStats 392 totalloc -= size; 393 assert(totalloc >= 0); 394 #endif 395 } 396 397 static void brel_after(char *buf, bufsize size) 398 { 399 struct bhead *b = BH(buf - sizeof(struct bhead)); 400 struct bhead *bn; 401 bufsize new_size = size; 402 bufsize free_size; 403 404 /* Select the size in the same way as in bget() */ 405 if (new_size < SizeQ) 406 new_size = SizeQ; 407 #ifdef SizeQuant 408 #if SizeQuant > 1 409 new_size = (new_size + (SizeQuant - 1)) & (~(SizeQuant - 1)); 410 #endif 411 #endif 412 new_size += sizeof(struct bhead); 413 assert(new_size <= -b->bsize); 414 415 /* 416 * Check if there's enough space at the end of the buffer to be 417 * able to free anything. 418 */ 419 free_size = -b->bsize - new_size; 420 if (free_size < SizeQ + sizeof(struct bhead)) 421 return; 422 423 bn = BH((char *)b - b->bsize); 424 /* 425 * Set the new size of the buffer; 426 */ 427 b->bsize = -new_size; 428 if (bn->bsize > 0) { 429 /* Next buffer is free, consolidate with that buffer */ 430 struct bfhead *bfn = BFH(bn); 431 struct bfhead *nbf = BFH((char *)b + new_size); 432 struct bhead *bnn = BH((char *)bn + bn->bsize); 433 434 assert(bfn->bh.prevfree == 0); 435 assert(bnn->prevfree == bfn->bh.bsize); 436 437 /* Construct the new free header */ 438 nbf->bh.prevfree = 0; 439 nbf->bh.bsize = bfn->bh.bsize + free_size; 440 441 /* Update the buffer after this to point to this header */ 442 bnn->prevfree += free_size; 443 444 /* 445 * Unlink the previous free buffer and link the new free 446 * buffer. 447 */ 448 assert(bfn->ql.blink->ql.flink == bfn); 449 assert(bfn->ql.flink->ql.blink == bfn); 450 451 /* Assing blink and flink from old free buffer */ 452 nbf->ql.blink = bfn->ql.blink; 453 nbf->ql.flink = bfn->ql.flink; 454 455 /* Replace the old free buffer with the new one */ 456 nbf->ql.blink->ql.flink = nbf; 457 nbf->ql.flink->ql.blink = nbf; 458 } else { 459 /* New buffer is allocated, create a new free buffer */ 460 create_free_block(BFH((char *)b + new_size), free_size, bn); 461 } 462 463 #ifdef BufStats 464 totalloc -= free_size; 465 assert(totalloc >= 0); 466 #endif 467 468 } 469 470 static void *raw_memalign(size_t hdr_size, size_t ftr_size, size_t alignment, 471 size_t size) 472 { 473 size_t s; 474 uintptr_t b; 475 476 raw_malloc_validate_pools(); 477 478 if (!IS_POWER_OF_TWO(alignment)) 479 return NULL; 480 481 /* 482 * Normal malloc with headers always returns something SizeQuant 483 * aligned. 484 */ 485 if (alignment <= SizeQuant) 486 return raw_malloc(hdr_size, ftr_size, size); 487 488 s = hdr_size + ftr_size + alignment + size + 489 SizeQ + sizeof(struct bhead); 490 491 /* Check wapping */ 492 if (s < alignment || s < size) 493 return NULL; 494 495 b = (uintptr_t)bget(s); 496 if (!b) 497 return NULL; 498 499 if ((b + hdr_size) & (alignment - 1)) { 500 /* 501 * Returned buffer is not aligned as requested if the 502 * hdr_size is added. Find an offset into the buffer 503 * that is far enough in to the buffer to be able to free 504 * what's in front. 505 */ 506 uintptr_t p; 507 508 /* 509 * Find the point where the buffer including supplied 510 * header size should start. 511 */ 512 p = b + hdr_size + alignment; 513 p &= ~(alignment - 1); 514 p -= hdr_size; 515 if ((p - b) < (SizeQ + sizeof(struct bhead))) 516 p += alignment; 517 assert((p + hdr_size + ftr_size + size) <= (b + s)); 518 519 /* Free the front part of the buffer */ 520 brel_before((void *)b, (void *)p); 521 522 /* Set the new start of the buffer */ 523 b = p; 524 } 525 526 /* 527 * Since b is now aligned, release what we don't need at the end of 528 * the buffer. 529 */ 530 brel_after((void *)b, hdr_size + ftr_size + size); 531 532 raw_malloc_save_max_alloced_size(); 533 534 return (void *)b; 535 } 536 537 /* Most of the stuff in this function is copied from bgetr() in bget.c */ 538 static bufsize bget_buf_size(void *buf) 539 { 540 bufsize osize; /* Old size of buffer */ 541 struct bhead *b; 542 543 b = BH(((char *)buf) - sizeof(struct bhead)); 544 osize = -b->bsize; 545 #ifdef BECtl 546 if (osize == 0) { 547 /* Buffer acquired directly through acqfcn. */ 548 struct bdhead *bd; 549 550 bd = BDH(((char *)buf) - sizeof(struct bdhead)); 551 osize = bd->tsize - sizeof(struct bdhead); 552 } else 553 #endif 554 osize -= sizeof(struct bhead); 555 assert(osize > 0); 556 return osize; 557 } 558 559 #ifdef ENABLE_MDBG 560 561 struct mdbg_hdr { 562 const char *fname; 563 uint16_t line; 564 bool ignore; 565 uint32_t pl_size; 566 uint32_t magic; 567 }; 568 569 #define MDBG_HEADER_MAGIC 0xadadadad 570 #define MDBG_FOOTER_MAGIC 0xecececec 571 572 /* TODO make this a per thread variable */ 573 static enum mdbg_mode mdbg_mode = MDBG_MODE_DYNAMIC; 574 575 static size_t mdbg_get_ftr_size(size_t pl_size) 576 { 577 size_t ftr_pad = ROUNDUP(pl_size, sizeof(uint32_t)) - pl_size; 578 579 return ftr_pad + sizeof(uint32_t); 580 } 581 582 583 static uint32_t *mdbg_get_footer(struct mdbg_hdr *hdr) 584 { 585 uint32_t *footer; 586 587 footer = (uint32_t *)((uint8_t *)(hdr + 1) + hdr->pl_size + 588 mdbg_get_ftr_size(hdr->pl_size)); 589 footer--; 590 return footer; 591 } 592 593 static void mdbg_update_hdr(struct mdbg_hdr *hdr, const char *fname, 594 int lineno, size_t pl_size) 595 { 596 uint32_t *footer; 597 598 hdr->fname = fname; 599 hdr->line = lineno; 600 hdr->pl_size = pl_size; 601 hdr->magic = MDBG_HEADER_MAGIC; 602 hdr->ignore = mdbg_mode == MDBG_MODE_STATIC; 603 604 footer = mdbg_get_footer(hdr); 605 *footer = MDBG_FOOTER_MAGIC; 606 } 607 608 void *mdbg_malloc(const char *fname, int lineno, size_t size) 609 { 610 struct mdbg_hdr *hdr; 611 612 COMPILE_TIME_ASSERT(sizeof(struct mdbg_hdr) == sizeof(uint32_t) * 4); 613 614 hdr = raw_malloc(sizeof(struct mdbg_hdr), 615 mdbg_get_ftr_size(size), size); 616 if (hdr) { 617 mdbg_update_hdr(hdr, fname, lineno, size); 618 hdr++; 619 } 620 return hdr; 621 } 622 623 static void assert_header(struct mdbg_hdr *hdr) 624 { 625 assert(hdr->magic == MDBG_HEADER_MAGIC); 626 assert(*mdbg_get_footer(hdr) == MDBG_FOOTER_MAGIC); 627 } 628 629 void mdbg_free(void *ptr) 630 { 631 struct mdbg_hdr *hdr = ptr; 632 633 if (hdr) { 634 hdr--; 635 assert_header(hdr); 636 hdr->magic = 0; 637 *mdbg_get_footer(hdr) = 0; 638 raw_free(hdr); 639 } 640 } 641 642 void *mdbg_calloc(const char *fname, int lineno, size_t nmemb, size_t size) 643 { 644 struct mdbg_hdr *hdr; 645 646 hdr = raw_calloc(sizeof(struct mdbg_hdr), 647 mdbg_get_ftr_size(nmemb * size), nmemb, size); 648 if (hdr) { 649 mdbg_update_hdr(hdr, fname, lineno, nmemb * size); 650 hdr++; 651 } 652 return hdr; 653 } 654 655 void *mdbg_realloc(const char *fname, int lineno, void *ptr, size_t size) 656 { 657 struct mdbg_hdr *hdr = ptr; 658 659 if (hdr) { 660 hdr--; 661 assert_header(hdr); 662 } 663 hdr = raw_realloc(hdr, sizeof(struct mdbg_hdr), 664 mdbg_get_ftr_size(size), size); 665 if (hdr) { 666 mdbg_update_hdr(hdr, fname, lineno, size); 667 hdr++; 668 } 669 return hdr; 670 } 671 672 void *mdbg_memalign(const char *fname, int lineno, size_t alignment, 673 size_t size) 674 { 675 struct mdbg_hdr *hdr; 676 677 hdr = raw_memalign(sizeof(struct mdbg_hdr), mdbg_get_ftr_size(size), 678 alignment, size); 679 if (hdr) { 680 mdbg_update_hdr(hdr, fname, lineno, size); 681 hdr++; 682 } 683 return hdr; 684 } 685 686 687 static void *get_payload_start_size(void *raw_buf, size_t *size) 688 { 689 struct mdbg_hdr *hdr = raw_buf; 690 691 assert(bget_buf_size(hdr) >= hdr->pl_size); 692 *size = hdr->pl_size; 693 return hdr + 1; 694 } 695 696 void mdbg_check(int bufdump) 697 { 698 struct bpool_iterator itr; 699 void *b; 700 701 raw_malloc_validate_pools(); 702 703 BPOOL_FOREACH(&itr, &b) { 704 struct mdbg_hdr *hdr = (struct mdbg_hdr *)b; 705 706 assert_header(hdr); 707 708 if (bufdump > 0 || !hdr->ignore) { 709 const char *fname = hdr->fname; 710 711 if (!fname) 712 fname = "unknown"; 713 714 DMSG("%s buffer: %d bytes %s:%d\n", 715 hdr->ignore ? "Ignore" : "Orphaned", 716 hdr->pl_size, fname, hdr->line); 717 } 718 } 719 720 } 721 722 enum mdbg_mode mdbg_set_mode(enum mdbg_mode mode) 723 { 724 enum mdbg_mode old_mode = mdbg_mode; 725 726 mdbg_mode = mode; 727 return old_mode; 728 } 729 730 #else 731 732 void *malloc(size_t size) 733 { 734 return raw_malloc(0, 0, size); 735 } 736 737 void free(void *ptr) 738 { 739 raw_free(ptr); 740 } 741 742 void *calloc(size_t nmemb, size_t size) 743 { 744 return raw_calloc(0, 0, nmemb, size); 745 } 746 747 void *realloc(void *ptr, size_t size) 748 { 749 return raw_realloc(ptr, 0, 0, size); 750 } 751 752 void *memalign(size_t alignment, size_t size) 753 { 754 return raw_memalign(0, 0, alignment, size); 755 } 756 757 static void *get_payload_start_size(void *ptr, size_t *size) 758 { 759 *size = bget_buf_size(ptr); 760 return ptr; 761 } 762 763 #endif 764 765 766 767 void malloc_init(void *buf, size_t len) 768 { 769 /* Must not be called twice */ 770 assert(!malloc_pool); 771 772 malloc_add_pool(buf, len); 773 } 774 775 void malloc_add_pool(void *buf, size_t len) 776 { 777 void *p; 778 size_t l; 779 uintptr_t start = (uintptr_t)buf; 780 uintptr_t end = start + len; 781 enum mdbg_mode old_mode = mdbg_set_mode(MDBG_MODE_STATIC); 782 783 start = ROUNDUP(start, SizeQuant); 784 end = ROUNDDOWN(end, SizeQuant); 785 assert(start < end); 786 787 bpool((void *)start, end - start); 788 789 l = malloc_pool_len + 1; 790 p = realloc(malloc_pool, sizeof(struct malloc_pool) * l); 791 assert(p); 792 malloc_pool = p; 793 malloc_pool[malloc_pool_len].buf = (void *)start; 794 malloc_pool[malloc_pool_len].len = end - start; 795 malloc_pool_len = l; 796 mdbg_set_mode(old_mode); 797 } 798 799 bool malloc_buffer_is_within_alloced(void *buf, size_t len) 800 { 801 struct bpool_iterator itr; 802 void *b; 803 uint8_t *start_buf = buf; 804 uint8_t *end_buf = start_buf + len; 805 806 raw_malloc_validate_pools(); 807 808 /* Check for wrapping */ 809 if (start_buf > end_buf) 810 return false; 811 812 BPOOL_FOREACH(&itr, &b) { 813 uint8_t *start_b; 814 uint8_t *end_b; 815 size_t s; 816 817 start_b = get_payload_start_size(b, &s); 818 end_b = start_b + s; 819 820 if (start_buf >= start_b && end_buf <= end_b) 821 return true; 822 } 823 return false; 824 } 825 826 bool malloc_buffer_overlaps_heap(void *buf, size_t len) 827 { 828 uintptr_t buf_start = (uintptr_t) buf; 829 uintptr_t buf_end = buf_start + len; 830 size_t n; 831 832 raw_malloc_validate_pools(); 833 834 for (n = 0; n < malloc_pool_len; n++) { 835 uintptr_t pool_start = (uintptr_t)malloc_pool[n].buf; 836 uintptr_t pool_end = pool_start + malloc_pool[n].len; 837 838 if (buf_start > buf_end || pool_start > pool_end) 839 return true; /* Wrapping buffers, shouldn't happen */ 840 841 if (buf_end > pool_start || buf_start < pool_end) 842 return true; 843 } 844 845 return false; 846 } 847