| @@ -35,6 +35,7 @@ · 34 unmodified lines |
| 35 | #endif | 35 | #endif |
| 36 | | 36 | |
| 37 | #define BOUND_DEBUG | 37 | #define BOUND_DEBUG |
| | 38 | #define BOUND_STATISTIC |
| 38 | | 39 | |
| 39 | #ifdef BOUND_DEBUG | 40 | #ifdef BOUND_DEBUG |
| 40 | #define dprintf(a...) if (print_calls) fprintf(a) | 41 | #define dprintf(a...) if (print_calls) fprintf(a) |
| @@ -50,8 +51,7 @@ · 9 unmodified lines |
| 50 | || defined(__DragonFly__) \ | 51 | || defined(__DragonFly__) \ |
| 51 | || defined(__OpenBSD__) \ | 52 | || defined(__OpenBSD__) \ |
| 52 | || defined(__NetBSD__) \ | 53 | || defined(__NetBSD__) \ |
| 53 | || defined(__dietlibc__) \ | 54 | || defined(__dietlibc__) |
| 54 | || defined(_WIN32) | | |
| 55 | #undef HAVE_MEMALIGN | 55 | #undef HAVE_MEMALIGN |
| 56 | #define INIT_SEM() | 56 | #define INIT_SEM() |
| 57 | #define EXIT_SEM() | 57 | #define EXIT_SEM() |
| @@ -59,6 +59,16 @@ · 1 unmodified line |
| 59 | #define POST_SEM() | 59 | #define POST_SEM() |
| 60 | #define HAS_ENVIRON 0 | 60 | #define HAS_ENVIRON 0 |
| 61 | #define MALLOC_REDIR (0) | 61 | #define MALLOC_REDIR (0) |
| | 62 | #elif defined(_WIN32) |
| | 63 | #include <windows.h> |
| | 64 | #undef HAVE_MEMALIGN |
| | 65 | static CRITICAL_SECTION bounds_sem; |
| | 66 | #define INIT_SEM() InitializeCriticalSection(&bounds_sem) |
| | 67 | #define EXIT_SEM() DeleteCriticalSection(&bounds_sem) |
| | 68 | #define WAIT_SEM() EnterCriticalSection(&bounds_sem) |
| | 69 | #define POST_SEM() LeaveCriticalSection(&bounds_sem) |
| | 70 | #define HAS_ENVIRON 0 |
| | 71 | #define MALLOC_REDIR (0) |
| 62 | #else | 72 | #else |
| 63 | #include <sys/mman.h> | 73 | #include <sys/mman.h> |
| 64 | #include <errno.h> | 74 | #include <errno.h> |
| @@ -86,6 +96,7 @@ static unsigned char initial_pool[256]; · 21 unmodified lines |
| 86 | #define TCC_TYPE_CALLOC (2) | 96 | #define TCC_TYPE_CALLOC (2) |
| 87 | #define TCC_TYPE_REALLOC (3) | 97 | #define TCC_TYPE_REALLOC (3) |
| 88 | #define TCC_TYPE_MEMALIGN (4) | 98 | #define TCC_TYPE_MEMALIGN (4) |
| | 99 | #define TCC_TYPE_STRDUP (5) |
| 89 | | 100 | |
| 90 | /* this pointer is generated when bound check is incorrect */ | 101 | /* this pointer is generated when bound check is incorrect */ |
| 91 | #define INVALID_POINTER ((void *)(-2)) | 102 | #define INVALID_POINTER ((void *)(-2)) |
| @@ -149,9 +160,45 @@ static alloca_list_type *alloca_list = NULL; · 57 unmodified lines |
| 149 | static int inited = 0; | 160 | static int inited = 0; |
| 150 | static int print_calls = 0; | 161 | static int print_calls = 0; |
| 151 | static int print_heap = 0; | 162 | static int print_heap = 0; |
| | 163 | static int print_statistic = 0; |
| 152 | static int never_fatal = 0; | 164 | static int never_fatal = 0; |
| 153 | static int no_checking = 0; | 165 | static int no_checking = 0; |
| 154 | | 166 | |
| | 167 | #ifdef BOUND_STATISTIC |
| | 168 | static unsigned long bound_ptr_add_count; |
| | 169 | static unsigned long bound_ptr_indir1_count; |
| | 170 | static unsigned long bound_ptr_indir2_count; |
| | 171 | static unsigned long bound_ptr_indir4_count; |
| | 172 | static unsigned long bound_ptr_indir8_count; |
| | 173 | static unsigned long bound_ptr_indir12_count; |
| | 174 | static unsigned long bound_ptr_indir16_count; |
| | 175 | static unsigned long bound_local_new_count; |
| | 176 | static unsigned long bound_local_delete_count; |
| | 177 | static unsigned long bound_malloc_count; |
| | 178 | static unsigned long bound_calloc_count; |
| | 179 | static unsigned long bound_realloc_count; |
| | 180 | static unsigned long bound_free_count; |
| | 181 | static unsigned long bound_memalign_count; |
| | 182 | static unsigned long bound_mmap_count; |
| | 183 | static unsigned long bound_munmap_count; |
| | 184 | static unsigned long bound_alloca_count; |
| | 185 | static unsigned long bound_mempcy_count; |
| | 186 | static unsigned long bound_memcmp_count; |
| | 187 | static unsigned long bound_memmove_count; |
| | 188 | static unsigned long bound_memset_count; |
| | 189 | static unsigned long bound_strlen_count; |
| | 190 | static unsigned long bound_strcpy_count; |
| | 191 | static unsigned long bound_strncpy_count; |
| | 192 | static unsigned long bound_strcmp_count; |
| | 193 | static unsigned long bound_strncmp_count; |
| | 194 | static unsigned long bound_strcat_count; |
| | 195 | static unsigned long bound_strchr_count; |
| | 196 | static unsigned long bound_strdup_count; |
| | 197 | #define INCR_COUNT(x) x++ |
| | 198 | #else |
| | 199 | #define INCR_COUNT(x) |
| | 200 | #endif |
| | 201 | |
| 155 | /* enable/disable checking. This can be used for signal handlers. */ | 202 | /* enable/disable checking. This can be used for signal handlers. */ |
| 156 | void __bound_checking (int no_check) | 203 | void __bound_checking (int no_check) |
| 157 | { | 204 | { |
| @@ -186,6 +233,7 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 28 unmodified lines |
| 186 | __FILE__, __FUNCTION__, p, (unsigned)offset); | 233 | __FILE__, __FUNCTION__, p, (unsigned)offset); |
| 187 | | 234 | |
| 188 | WAIT_SEM (); | 235 | WAIT_SEM (); |
| | 236 | INCR_COUNT(bound_ptr_add_count); |
| 189 | if (tree) { | 237 | if (tree) { |
| 190 | tree = splay (addr, tree); | 238 | tree = splay (addr, tree); |
| 191 | addr -= tree->start; | 239 | addr -= tree->start; |
| @@ -223,6 +271,7 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ · 31 unmodified lines |
| 223 | dprintf(stderr, "%s %s: %p 0x%x start\n", \ | 271 | dprintf(stderr, "%s %s: %p 0x%x start\n", \ |
| 224 | __FILE__, __FUNCTION__, p, (unsigned)offset); \ | 272 | __FILE__, __FUNCTION__, p, (unsigned)offset); \ |
| 225 | WAIT_SEM (); \ | 273 | WAIT_SEM (); \ |
| | 274 | INCR_COUNT(bound_ptr_indir ## dsize ## _count); \ |
| 226 | if (tree) { \ | 275 | if (tree) { \ |
| 227 | tree = splay (addr, tree); \ | 276 | tree = splay (addr, tree); \ |
| 228 | addr -= tree->start; \ | 277 | addr -= tree->start; \ |
| @@ -284,6 +333,7 @@ void FASTCALL __bound_local_new(void *p1) · 55 unmodified lines |
| 284 | addr = p[0]; | 333 | addr = p[0]; |
| 285 | if (addr == 0) | 334 | if (addr == 0) |
| 286 | break; | 335 | break; |
| | 336 | INCR_COUNT(bound_local_new_count); |
| 287 | if (addr == 1) { | 337 | if (addr == 1) { |
| 288 | dprintf(stderr, "%s, %s() alloca/vla used\n", | 338 | dprintf(stderr, "%s, %s() alloca/vla used\n", |
| 289 | __FILE__, __FUNCTION__); | 339 | __FILE__, __FUNCTION__); |
| @@ -315,6 +365,7 @@ void FASTCALL __bound_local_delete(void *p1) · 25 unmodified lines |
| 315 | addr = p[0]; | 365 | addr = p[0]; |
| 316 | if (addr == 0) | 366 | if (addr == 0) |
| 317 | break; | 367 | break; |
| | 368 | INCR_COUNT(bound_local_delete_count); |
| 318 | if (addr == 1) { | 369 | if (addr == 1) { |
| 319 | while (alloca_list && alloca_list->fp == fp) { | 370 | while (alloca_list && alloca_list->fp == fp) { |
| 320 | alloca_list_type *next = alloca_list->next; | 371 | alloca_list_type *next = alloca_list->next; |
| @@ -350,6 +401,7 @@ void __bound_init(void) · 29 unmodified lines |
| 350 | | 401 | |
| 351 | print_calls = getenv ("TCC_BOUNDS_PRINT_CALLS") != NULL; | 402 | print_calls = getenv ("TCC_BOUNDS_PRINT_CALLS") != NULL; |
| 352 | print_heap = getenv ("TCC_BOUNDS_PRINT_HEAP") != NULL; | 403 | print_heap = getenv ("TCC_BOUNDS_PRINT_HEAP") != NULL; |
| | 404 | print_statistic = getenv ("TCC_BOUNDS_PRINT_STATISTIC") != NULL; |
| 353 | never_fatal = getenv ("TCC_BOUNDS_NEVER_FATAL") != NULL; | 405 | never_fatal = getenv ("TCC_BOUNDS_NEVER_FATAL") != NULL; |
| 354 | | 406 | |
| 355 | dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__); | 407 | dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__); |
| @@ -444,7 +496,7 @@ void __attribute__((destructor)) __bound_exit(void) · 88 unmodified lines |
| 444 | { | 496 | { |
| 445 | int i; | 497 | int i; |
| 446 | static const char * const alloc_type[] = { | 498 | static const char * const alloc_type[] = { |
| 447 | "", "malloc", "calloc", "realloc", "memalign" | 499 | "", "malloc", "calloc", "realloc", "memalign", "strdup" |
| 448 | }; | 500 | }; |
| 449 | | 501 | |
| 450 | dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__); | 502 | dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__); |
| @@ -488,6 +540,39 @@ void __attribute__((destructor)) __bound_exit(void) · 37 unmodified lines |
| 488 | } | 540 | } |
| 489 | EXIT_SEM (); | 541 | EXIT_SEM (); |
| 490 | inited = 0; | 542 | inited = 0; |
| | 543 | #ifdef BOUND_STATISTIC |
| | 544 | if (print_statistic) { |
| | 545 | fprintf (stderr, "bound_ptr_add_count %llu\n", bound_ptr_add_count); |
| | 546 | fprintf (stderr, "bound_ptr_indir1_count %llu\n", bound_ptr_indir1_count); |
| | 547 | fprintf (stderr, "bound_ptr_indir2_count %llu\n", bound_ptr_indir2_count); |
| | 548 | fprintf (stderr, "bound_ptr_indir4_count %llu\n", bound_ptr_indir4_count); |
| | 549 | fprintf (stderr, "bound_ptr_indir8_count %llu\n", bound_ptr_indir8_count); |
| | 550 | fprintf (stderr, "bound_ptr_indir12_count %llu\n", bound_ptr_indir12_count); |
| | 551 | fprintf (stderr, "bound_ptr_indir16_count %llu\n", bound_ptr_indir16_count); |
| | 552 | fprintf (stderr, "bound_local_new_count %llu\n", bound_local_new_count); |
| | 553 | fprintf (stderr, "bound_local_delete_count %llu\n", bound_local_delete_count); |
| | 554 | fprintf (stderr, "bound_malloc_count %llu\n", bound_malloc_count); |
| | 555 | fprintf (stderr, "bound_calloc_count %llu\n", bound_calloc_count); |
| | 556 | fprintf (stderr, "bound_realloc_count %llu\n", bound_realloc_count); |
| | 557 | fprintf (stderr, "bound_free_count %llu\n", bound_free_count); |
| | 558 | fprintf (stderr, "bound_memalign_count %llu\n", bound_memalign_count); |
| | 559 | fprintf (stderr, "bound_mmap_count %llu\n", bound_mmap_count); |
| | 560 | fprintf (stderr, "bound_munmap_count %llu\n", bound_munmap_count); |
| | 561 | fprintf (stderr, "bound_alloca_count %llu\n", bound_alloca_count); |
| | 562 | fprintf (stderr, "bound_mempcy_count %llu\n", bound_mempcy_count); |
| | 563 | fprintf (stderr, "bound_memcmp_count %llu\n", bound_memcmp_count); |
| | 564 | fprintf (stderr, "bound_memmove_count %llu\n", bound_memmove_count); |
| | 565 | fprintf (stderr, "bound_memset_count %llu\n", bound_memset_count); |
| | 566 | fprintf (stderr, "bound_strlen_count %llu\n", bound_strlen_count); |
| | 567 | fprintf (stderr, "bound_strcpy_count %llu\n", bound_strcpy_count); |
| | 568 | fprintf (stderr, "bound_strncpy_count %llu\n", bound_strncpy_count); |
| | 569 | fprintf (stderr, "bound_strcmp_count %llu\n", bound_strcmp_count); |
| | 570 | fprintf (stderr, "bound_strncmp_count %llu\n", bound_strncmp_count); |
| | 571 | fprintf (stderr, "bound_strcat_count %llu\n", bound_strcat_count); |
| | 572 | fprintf (stderr, "bound_strchr_count %llu\n", bound_strchr_count); |
| | 573 | fprintf (stderr, "bound_strdup_count %llu\n", bound_strdup_count); |
| | 574 | } |
| | 575 | #endif |
| 491 | } | 576 | } |
| 492 | } | 577 | } |
| 493 | | 578 | |
| @@ -516,6 +601,7 @@ void *__bound_malloc(size_t size, const void *caller) · 22 unmodified lines |
| 516 | separated by at least one byte. With the glibc malloc, it may | 601 | separated by at least one byte. With the glibc malloc, it may |
| 517 | be in fact not necessary */ | 602 | be in fact not necessary */ |
| 518 | WAIT_SEM (); | 603 | WAIT_SEM (); |
| | 604 | INCR_COUNT(bound_malloc_count); |
| 519 | #if MALLOC_REDIR | 605 | #if MALLOC_REDIR |
| 520 | ptr = malloc_redir (size); | 606 | ptr = malloc_redir (size); |
| 521 | #else | 607 | #else |
| @@ -544,6 +630,7 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) · 22 unmodified lines |
| 544 | void *ptr; | 630 | void *ptr; |
| 545 | | 631 | |
| 546 | WAIT_SEM (); | 632 | WAIT_SEM (); |
| | 633 | INCR_COUNT(bound_memalign_count); |
| 547 | | 634 | |
| 548 | #ifndef HAVE_MEMALIGN | 635 | #ifndef HAVE_MEMALIGN |
| 549 | if (align > 4) { | 636 | if (align > 4) { |
| @@ -599,6 +686,7 @@ void __bound_free(void *ptr, const void *caller) · 49 unmodified lines |
| 599 | dprintf(stderr, "%s, %s (%p)\n", __FILE__, __FUNCTION__, ptr); | 686 | dprintf(stderr, "%s, %s (%p)\n", __FILE__, __FUNCTION__, ptr); |
| 600 | | 687 | |
| 601 | WAIT_SEM (); | 688 | WAIT_SEM (); |
| | 689 | INCR_COUNT(bound_free_count); |
| 602 | tree = splay (addr, tree); | 690 | tree = splay (addr, tree); |
| 603 | if (tree->start == addr) { | 691 | if (tree->start == addr) { |
| 604 | if (tree->is_invalid) { | 692 | if (tree->is_invalid) { |
| @@ -645,6 +733,7 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller) · 40 unmodified lines |
| 645 | ptr = realloc (ptr, size); | 733 | ptr = realloc (ptr, size); |
| 646 | #endif | 734 | #endif |
| 647 | WAIT_SEM (); | 735 | WAIT_SEM (); |
| | 736 | INCR_COUNT(bound_realloc_count); |
| 648 | if (ptr) { | 737 | if (ptr) { |
| 649 | tree = splay_insert ((size_t) ptr, size, tree); | 738 | tree = splay_insert ((size_t) ptr, size, tree); |
| 650 | if (tree->start == (size_t) ptr) { | 739 | if (tree->start == (size_t) ptr) { |
| @@ -701,6 +790,7 @@ void *__bound_calloc(size_t nmemb, size_t size) · 50 unmodified lines |
| 701 | if (ptr) { | 790 | if (ptr) { |
| 702 | memset (ptr, 0, size); | 791 | memset (ptr, 0, size); |
| 703 | WAIT_SEM (); | 792 | WAIT_SEM (); |
| | 793 | INCR_COUNT(bound_calloc_count); |
| 704 | tree = splay_insert ((size_t) ptr, size, tree); | 794 | tree = splay_insert ((size_t) ptr, size, tree); |
| 705 | if (tree->start == (size_t) ptr) { | 795 | if (tree->start == (size_t) ptr) { |
| 706 | tree->type = TCC_TYPE_CALLOC; | 796 | tree->type = TCC_TYPE_CALLOC; |
| @@ -721,6 +811,7 @@ void *__bound_mmap (void *start, size_t size, int prot, · 14 unmodified lines |
| 721 | result = mmap (start, size, prot, flags, fd, offset); | 811 | result = mmap (start, size, prot, flags, fd, offset); |
| 722 | if (result) { | 812 | if (result) { |
| 723 | WAIT_SEM (); | 813 | WAIT_SEM (); |
| | 814 | INCR_COUNT(bound_mmap_count); |
| 724 | tree = splay_insert((size_t)result, size, tree); | 815 | tree = splay_insert((size_t)result, size, tree); |
| 725 | POST_SEM (); | 816 | POST_SEM (); |
| 726 | } | 817 | } |
| @@ -734,6 +825,7 @@ int __bound_munmap (void *start, size_t size) · 7 unmodified lines |
| 734 | dprintf(stderr, "%s, %s (%p, 0x%x)\n", | 825 | dprintf(stderr, "%s, %s (%p, 0x%x)\n", |
| 735 | __FILE__, __FUNCTION__, start, (unsigned)size); | 826 | __FILE__, __FUNCTION__, start, (unsigned)size); |
| 736 | WAIT_SEM (); | 827 | WAIT_SEM (); |
| | 828 | INCR_COUNT(bound_munmap_count); |
| 737 | tree = splay_delete ((size_t) start, tree); | 829 | tree = splay_delete ((size_t) start, tree); |
| 738 | POST_SEM (); | 830 | POST_SEM (); |
| 739 | result = munmap (start, size); | 831 | result = munmap (start, size); |
| @@ -751,6 +843,7 @@ void __bound_new_region(void *p, size_t size) · 11 unmodified lines |
| 751 | dprintf(stderr, "%s, %s (%p, 0x%x)\n", | 843 | dprintf(stderr, "%s, %s (%p, 0x%x)\n", |
| 752 | __FILE__, __FUNCTION__, p, (unsigned)size); | 844 | __FILE__, __FUNCTION__, p, (unsigned)size); |
| 753 | WAIT_SEM (); | 845 | WAIT_SEM (); |
| | 846 | INCR_COUNT(bound_alloca_count); |
| 754 | GET_CALLER_FP (fp); | 847 | GET_CALLER_FP (fp); |
| 755 | last = NULL; | 848 | last = NULL; |
| 756 | cur = alloca_list; | 849 | cur = alloca_list; |
| @@ -813,6 +906,7 @@ void *__bound_memcpy(void *dst, const void *src, size_t size) · 56 unmodified lines |
| 813 | { | 906 | { |
| 814 | void* p; | 907 | void* p; |
| 815 | | 908 | |
| | 909 | INCR_COUNT(bound_mempcy_count); |
| 816 | __bound_check(dst, size); | 910 | __bound_check(dst, size); |
| 817 | __bound_check(src, size); | 911 | __bound_check(src, size); |
| 818 | /* check also region overlap */ | 912 | /* check also region overlap */ |
| @@ -824,8 +918,17 @@ void *__bound_memcpy(void *dst, const void *src, size_t size) · 5 unmodified lines |
| 824 | return p; | 918 | return p; |
| 825 | } | 919 | } |
| 826 | | 920 | |
| | 921 | int __bound_memcmp(const void *s1, const void *s2, size_t size) |
| | 922 | { |
| | 923 | INCR_COUNT(bound_memcmp_count); |
| | 924 | __bound_check(s1, size); |
| | 925 | __bound_check(s2, size); |
| | 926 | return memcmp(s1, s2, size); |
| | 927 | } |
| | 928 | |
| 827 | void *__bound_memmove(void *dst, const void *src, size_t size) | 929 | void *__bound_memmove(void *dst, const void *src, size_t size) |
| 828 | { | 930 | { |
| | 931 | INCR_COUNT(bound_memmove_count); |
| 829 | __bound_check(dst, size); | 932 | __bound_check(dst, size); |
| 830 | __bound_check(src, size); | 933 | __bound_check(src, size); |
| 831 | return memmove(dst, src, size); | 934 | return memmove(dst, src, size); |
| @@ -833,25 +936,22 @@ void *__bound_memmove(void *dst, const void *src, size_t size) · 1 unmodified line |
| 833 | | 936 | |
| 834 | void *__bound_memset(void *dst, int c, size_t size) | 937 | void *__bound_memset(void *dst, int c, size_t size) |
| 835 | { | 938 | { |
| | 939 | INCR_COUNT(bound_memset_count); |
| 836 | __bound_check(dst, size); | 940 | __bound_check(dst, size); |
| 837 | return memset(dst, c, size); | 941 | return memset(dst, c, size); |
| 838 | } | 942 | } |
| 839 | | 943 | |
| 840 | /* XXX: could be optimized */ | | |
| 841 | int __bound_strlen(const char *s) | 944 | int __bound_strlen(const char *s) |
| 842 | { | 945 | { |
| 843 | const char *p; | 946 | const char *p = s; |
| 844 | size_t len; | 947 | size_t len; |
| 845 | | 948 | |
| 846 | len = 0; | 949 | INCR_COUNT(bound_strlen_count); |
| 847 | for(;;) { | 950 | while (*p++); |
| 848 | p = __bound_ptr_indir1((char *)s, len); | 951 | len = (p - s) - 1; |
| 849 | if (p == INVALID_POINTER) | 952 | p = __bound_ptr_indir1((char *)s, len); |
| 850 | bound_error("bad pointer in strlen()"); | 953 | if (p == INVALID_POINTER) |
| 851 | if (*p == '\0') | 954 | bound_error("bad pointer in strlen()"); |
| 852 | break; | | |
| 853 | len++; | | |
| 854 | } | | |
| 855 | return len; | 955 | return len; |
| 856 | } | 956 | } |
| 857 | | 957 | |
| @@ -860,11 +960,101 @@ char *__bound_strcpy(char *dst, const char *src) · 2 unmodified lines |
| 860 | size_t len; | 960 | size_t len; |
| 861 | void *p; | 961 | void *p; |
| 862 | | 962 | |
| | 963 | INCR_COUNT(bound_strcpy_count); |
| 863 | len = __bound_strlen(src); | 964 | len = __bound_strlen(src); |
| 864 | p = __bound_memcpy(dst, src, len + 1); | 965 | p = __bound_memcpy(dst, src, len + 1); |
| 865 | return p; | 966 | return p; |
| 866 | } | 967 | } |
| 867 | | 968 | |
| | 969 | char *__bound_strncpy(char *dst, const char *src, size_t n) |
| | 970 | { |
| | 971 | size_t len; |
| | 972 | void *p; |
| | 973 | |
| | 974 | INCR_COUNT(bound_strncpy_count); |
| | 975 | __bound_check(dst, n); |
| | 976 | __bound_check(src, n); |
| | 977 | return strncpy (dst, src, n); |
| | 978 | } |
| | 979 | |
| | 980 | int __bound_strcmp(const char *s1, const char *s2) |
| | 981 | { |
| | 982 | const unsigned char *u1 = (const unsigned char *) s1; |
| | 983 | const unsigned char *u2 = (const unsigned char *) s2; |
| | 984 | |
| | 985 | INCR_COUNT(bound_strcmp_count); |
| | 986 | while (*u1 && *u1 == *u2) { |
| | 987 | u1++; |
| | 988 | u2++; |
| | 989 | } |
| | 990 | __bound_check(s1, ((const char *)u1 - s1) + 1); |
| | 991 | __bound_check(s2, ((const char *)u2 - s2) + 1); |
| | 992 | return (*u1 - *u2); |
| | 993 | } |
| | 994 | |
| | 995 | int __bound_strncmp(const char *s1, const char *s2, size_t n) |
| | 996 | { |
| | 997 | INCR_COUNT(bound_strncmp_count); |
| | 998 | __bound_check(s1, n); |
| | 999 | __bound_check(s2, n); |
| | 1000 | return strncmp(s1, s2, n); |
| | 1001 | } |
| | 1002 | |
| | 1003 | char *__bound_strcat(char *dest, const char *src) |
| | 1004 | { |
| | 1005 | char *r = dest; |
| | 1006 | const char *s = src; |
| | 1007 | |
| | 1008 | INCR_COUNT(bound_strcat_count); |
| | 1009 | while (*dest++); |
| | 1010 | dest--; |
| | 1011 | while ((*dest++ = *src++) != 0); |
| | 1012 | __bound_check(r, dest - r); |
| | 1013 | __bound_check(s, src - s); |
| | 1014 | return r; |
| | 1015 | } |
| | 1016 | |
| | 1017 | char *__bound_strchr(const char *string, int ch) |
| | 1018 | { |
| | 1019 | const unsigned char *s = (const unsigned char *) string; |
| | 1020 | unsigned char c = ch; |
| | 1021 | |
| | 1022 | INCR_COUNT(bound_strchr_count); |
| | 1023 | while (*s) { |
| | 1024 | if (*s == c) { |
| | 1025 | break; |
| | 1026 | } |
| | 1027 | s++; |
| | 1028 | } |
| | 1029 | __bound_check(string, ((const char *)s - string) + 1); |
| | 1030 | return *s == c ? (char *) s : NULL; |
| | 1031 | } |
| | 1032 | |
| | 1033 | char *__bound_strdup(const char *s) |
| | 1034 | { |
| | 1035 | const char *p = s; |
| | 1036 | char *new; |
| | 1037 | |
| | 1038 | INCR_COUNT(bound_strdup_count); |
| | 1039 | while (*p++); |
| | 1040 | __bound_check(s, p - s); |
| | 1041 | #if MALLOC_REDIR |
| | 1042 | new = malloc_redir (p - s); |
| | 1043 | #else |
| | 1044 | new = malloc (p - s); |
| | 1045 | #endif |
| | 1046 | if (new) { |
| | 1047 | WAIT_SEM (); |
| | 1048 | tree = splay_insert((size_t)new, p - s, tree); |
| | 1049 | if (tree->start == (size_t) new) { |
| | 1050 | tree->type = TCC_TYPE_STRDUP; |
| | 1051 | } |
| | 1052 | memcpy (new, s, p - s); |
| | 1053 | POST_SEM (); |
| | 1054 | } |
| | 1055 | return new; |
| | 1056 | } |
| | 1057 | |
| 868 | /* | 1058 | /* |
| 869 | An implementation of top-down splaying with sizes | 1059 | An implementation of top-down splaying with sizes |
| 870 | D. Sleator <sleator@cs.cmu.edu>, January 1994. | 1060 | D. Sleator <sleator@cs.cmu.edu>, January 1994. |