| @@ -221,7 +221,8 @@ static void bound_alloc_error(void) · 220 unmodified lines |
| 221 | | 221 | |
| 222 | /* return '(p + offset)' for pointer arithmetic (a pointer can reach | 222 | /* return '(p + offset)' for pointer arithmetic (a pointer can reach |
| 223 | the end of a region in this case */ | 223 | the end of a region in this case */ |
| 224 | void * FASTCALL __bound_ptr_add(void *p, size_t offset) | 224 | void * FASTCALL __bound_ptr_add(void *p, size_t offset, |
| | 225 | size_t line, const char *filename) |
| 225 | { | 226 | { |
| 226 | size_t addr = (size_t)p; | 227 | size_t addr = (size_t)p; |
| 227 | | 228 | |
| @@ -229,8 +230,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 1 unmodified line |
| 229 | return p + offset; | 230 | return p + offset; |
| 230 | } | 231 | } |
| 231 | | 232 | |
| 232 | dprintf(stderr, "%s %s: %p 0x%x\n", | 233 | dprintf(stderr, "%s %s (%s:%u): %p 0x%x\n", |
| 233 | __FILE__, __FUNCTION__, p, (unsigned)offset); | 234 | __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); |
| 234 | | 235 | |
| 235 | WAIT_SEM (); | 236 | WAIT_SEM (); |
| 236 | INCR_COUNT(bound_ptr_add_count); | 237 | INCR_COUNT(bound_ptr_add_count); |
| @@ -249,8 +250,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 12 unmodified lines |
| 249 | if (addr <= tree->size) { | 250 | if (addr <= tree->size) { |
| 250 | addr += offset; | 251 | addr += offset; |
| 251 | if (tree->is_invalid || addr > tree->size) { | 252 | if (tree->is_invalid || addr > tree->size) { |
| 252 | fprintf(stderr,"%s %s: %p is outside of the region\n", | 253 | fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", |
| 253 | __FILE__, __FUNCTION__, p + offset); | 254 | __FILE__, __FUNCTION__, filename, line, p + offset); |
| 254 | if (never_fatal == 0) { | 255 | if (never_fatal == 0) { |
| 255 | POST_SEM (); | 256 | POST_SEM (); |
| 256 | return INVALID_POINTER; /* return an invalid pointer */ | 257 | return INVALID_POINTER; /* return an invalid pointer */ |
| @@ -264,44 +265,45 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 7 unmodified lines |
| 264 | | 265 | |
| 265 | /* return '(p + offset)' for pointer indirection (the resulting must | 266 | /* return '(p + offset)' for pointer indirection (the resulting must |
| 266 | be strictly inside the region */ | 267 | be strictly inside the region */ |
| 267 | #define BOUND_PTR_INDIR(dsize) \ | 268 | #define BOUND_PTR_INDIR(dsize) \ |
| 268 | void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ | 269 | void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \ |
| 269 | { \ | 270 | size_t line, const char *filename) \ |
| 270 | size_t addr = (size_t)p; \ | 271 | { \ |
| 271 | \ | 272 | size_t addr = (size_t)p; \ |
| 272 | if (no_checking) { \ | 273 | \ |
| 273 | return p + offset; \ | 274 | if (no_checking) { \ |
| 274 | } \ | 275 | return p + offset; \ |
| 275 | dprintf(stderr, "%s %s: %p 0x%x start\n", \ | 276 | } \ |
| 276 | __FILE__, __FUNCTION__, p, (unsigned)offset); \ | 277 | dprintf(stderr, "%s %s (%s:%u): %p 0x%x start\n", \ |
| 277 | WAIT_SEM (); \ | 278 | __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); \ |
| 278 | INCR_COUNT(bound_ptr_indir ## dsize ## _count); \ | 279 | WAIT_SEM (); \ |
| 279 | if (tree) { \ | 280 | INCR_COUNT(bound_ptr_indir ## dsize ## _count); \ |
| 280 | addr -= tree->start; \ | 281 | if (tree) { \ |
| 281 | if (addr >= tree->size) { \ | 282 | addr -= tree->start; \ |
| 282 | addr = (size_t)p; \ | 283 | if (addr >= tree->size) { \ |
| 283 | tree = splay (addr, tree); \ | 284 | addr = (size_t)p; \ |
| 284 | addr -= tree->start; \ | 285 | tree = splay (addr, tree); \ |
| 285 | } \ | 286 | addr -= tree->start; \ |
| 286 | if (addr >= tree->size) { \ | 287 | } \ |
| 287 | addr = (size_t)p; \ | 288 | if (addr >= tree->size) { \ |
| 288 | tree = splay_end (addr, tree); \ | 289 | addr = (size_t)p; \ |
| 289 | addr -= tree->start; \ | 290 | tree = splay_end (addr, tree); \ |
| 290 | } \ | 291 | addr -= tree->start; \ |
| 291 | if (addr <= tree->size) { \ | 292 | } \ |
| 292 | addr += offset + dsize; \ | 293 | if (addr <= tree->size) { \ |
| 293 | if (tree->is_invalid || addr > tree->size) { \ | 294 | addr += offset + dsize; \ |
| 294 | fprintf(stderr,"%s %s: %p is outside of the region\n", \ | 295 | if (tree->is_invalid || addr > tree->size) { \ |
| 295 | __FILE__, __FUNCTION__, p + offset); \ | 296 | fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", \ |
| 296 | if (never_fatal == 0) { \ | 297 | __FILE__, __FUNCTION__, filename, line, p + offset); \ |
| 297 | POST_SEM (); \ | 298 | if (never_fatal == 0) { \ |
| 298 | return INVALID_POINTER; /* return an invalid pointer */ \ | 299 | POST_SEM (); \ |
| 299 | } \ | 300 | return INVALID_POINTER; /* return an invalid pointer */ \ |
| 300 | } \ | 301 | } \ |
| 301 | } \ | 302 | } \ |
| 302 | } \ | 303 | } \ |
| 303 | POST_SEM (); \ | 304 | } \ |
| 304 | return p + offset; \ | 305 | POST_SEM (); \ |
| | 306 | return p + offset; \ |
| 305 | } | 307 | } |
| 306 | | 308 | |
| 307 | BOUND_PTR_INDIR(1) | 309 | BOUND_PTR_INDIR(1) |
| @@ -540,7 +542,7 @@ void __attribute__((destructor)) __bound_exit(void) · 232 unmodified lines |
| 540 | } | 542 | } |
| 541 | while (tree) { | 543 | while (tree) { |
| 542 | if (print_heap && tree->type != 0) { | 544 | if (print_heap && tree->type != 0) { |
| 543 | fprintf (stderr, "%s, %s() %s found size %ld\n", | 545 | fprintf (stderr, "%s, %s() %s found size %lu\n", |
| 544 | __FILE__, __FUNCTION__, alloc_type[tree->type], | 546 | __FILE__, __FUNCTION__, alloc_type[tree->type], |
| 545 | (unsigned long) tree->size); | 547 | (unsigned long) tree->size); |
| 546 | } | 548 | } |
| @@ -621,7 +623,7 @@ void *__bound_malloc(size_t size, const void *caller) · 74 unmodified lines |
| 621 | | 623 | |
| 622 | if (ptr) { | 624 | if (ptr) { |
| 623 | tree = splay_insert ((size_t) ptr, size, tree); | 625 | tree = splay_insert ((size_t) ptr, size, tree); |
| 624 | if (tree->start == (size_t) ptr) { | 626 | if (tree && tree->start == (size_t) ptr) { |
| 625 | tree->type = TCC_TYPE_MALLOC; | 627 | tree->type = TCC_TYPE_MALLOC; |
| 626 | } | 628 | } |
| 627 | } | 629 | } |
| @@ -666,7 +668,7 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) · 38 unmodified lines |
| 666 | dprintf(stderr, "%s, %s (%p, 0x%x)\n", | 668 | dprintf(stderr, "%s, %s (%p, 0x%x)\n", |
| 667 | __FILE__, __FUNCTION__, ptr, (unsigned)size); | 669 | __FILE__, __FUNCTION__, ptr, (unsigned)size); |
| 668 | tree = splay_insert((size_t) ptr, size, tree); | 670 | tree = splay_insert((size_t) ptr, size, tree); |
| 669 | if (tree->start == (size_t) ptr) { | 671 | if (tree && tree->start == (size_t) ptr) { |
| 670 | tree->type = TCC_TYPE_MEMALIGN; | 672 | tree->type = TCC_TYPE_MEMALIGN; |
| 671 | } | 673 | } |
| 672 | } | 674 | } |
| @@ -744,7 +746,7 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller) · 71 unmodified lines |
| 744 | INCR_COUNT(bound_realloc_count); | 746 | INCR_COUNT(bound_realloc_count); |
| 745 | if (ptr) { | 747 | if (ptr) { |
| 746 | tree = splay_insert ((size_t) ptr, size, tree); | 748 | tree = splay_insert ((size_t) ptr, size, tree); |
| 747 | if (tree->start == (size_t) ptr) { | 749 | if (tree && tree->start == (size_t) ptr) { |
| 748 | tree->type = TCC_TYPE_REALLOC; | 750 | tree->type = TCC_TYPE_REALLOC; |
| 749 | } | 751 | } |
| 750 | } | 752 | } |
| @@ -761,7 +763,7 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller) · 10 unmodified lines |
| 761 | #endif | 763 | #endif |
| 762 | if (ptr) { | 764 | if (ptr) { |
| 763 | tree = splay_insert ((size_t) ptr, size, tree); | 765 | tree = splay_insert ((size_t) ptr, size, tree); |
| 764 | if (tree->start == (size_t) ptr) { | 766 | if (tree && tree->start == (size_t) ptr) { |
| 765 | tree->type = TCC_TYPE_REALLOC; | 767 | tree->type = TCC_TYPE_REALLOC; |
| 766 | } | 768 | } |
| 767 | } | 769 | } |
| @@ -800,7 +802,7 @@ void *__bound_calloc(size_t nmemb, size_t size) · 32 unmodified lines |
| 800 | WAIT_SEM (); | 802 | WAIT_SEM (); |
| 801 | INCR_COUNT(bound_calloc_count); | 803 | INCR_COUNT(bound_calloc_count); |
| 802 | tree = splay_insert ((size_t) ptr, size, tree); | 804 | tree = splay_insert ((size_t) ptr, size, tree); |
| 803 | if (tree->start == (size_t) ptr) { | 805 | if (tree && tree->start == (size_t) ptr) { |
| 804 | tree->type = TCC_TYPE_CALLOC; | 806 | tree->type = TCC_TYPE_CALLOC; |
| 805 | } | 807 | } |
| 806 | POST_SEM (); | 808 | POST_SEM (); |
| @@ -899,13 +901,13 @@ void __bound_new_region(void *p, size_t size) · 92 unmodified lines |
| 899 | /* some useful checked functions */ | 901 | /* some useful checked functions */ |
| 900 | | 902 | |
| 901 | /* check that (p ... p + size - 1) lies inside 'p' region, if any */ | 903 | /* check that (p ... p + size - 1) lies inside 'p' region, if any */ |
| 902 | static void __bound_check(const void *p, size_t size) | 904 | static void __bound_check(const void *p, size_t size, const char *function) |
| 903 | { | 905 | { |
| 904 | if (no_checking) | 906 | if (no_checking) |
| 905 | return; | 907 | return; |
| 906 | if (size == 0) | 908 | if (size == 0) |
| 907 | return; | 909 | return; |
| 908 | p = __bound_ptr_add((void *)p, size); | 910 | p = __bound_ptr_add((void *)p, size, 0, function); |
| 909 | if (p == INVALID_POINTER) | 911 | if (p == INVALID_POINTER) |
| 910 | bound_error("invalid pointer"); | 912 | bound_error("invalid pointer"); |
| 911 | } | 913 | } |
| @@ -915,8 +917,8 @@ void *__bound_memcpy(void *dst, const void *src, size_t size) · 3 unmodified lines |
| 915 | void* p; | 917 | void* p; |
| 916 | | 918 | |
| 917 | INCR_COUNT(bound_mempcy_count); | 919 | INCR_COUNT(bound_mempcy_count); |
| 918 | __bound_check(dst, size); | 920 | __bound_check(dst, size, "memcpy"); |
| 919 | __bound_check(src, size); | 921 | __bound_check(src, size, "memcpy"); |
| 920 | /* check also region overlap */ | 922 | /* check also region overlap */ |
| 921 | if (no_checking == 0 && src >= dst && src < dst + size) | 923 | if (no_checking == 0 && src >= dst && src < dst + size) |
| 922 | bound_error("overlapping regions in memcpy()"); | 924 | bound_error("overlapping regions in memcpy()"); |
| @@ -929,23 +931,23 @@ void *__bound_memcpy(void *dst, const void *src, size_t size) · 6 unmodified lines |
| 929 | int __bound_memcmp(const void *s1, const void *s2, size_t size) | 931 | int __bound_memcmp(const void *s1, const void *s2, size_t size) |
| 930 | { | 932 | { |
| 931 | INCR_COUNT(bound_memcmp_count); | 933 | INCR_COUNT(bound_memcmp_count); |
| 932 | __bound_check(s1, size); | 934 | __bound_check(s1, size, "memcmp"); |
| 933 | __bound_check(s2, size); | 935 | __bound_check(s2, size, "memcmp"); |
| 934 | return memcmp(s1, s2, size); | 936 | return memcmp(s1, s2, size); |
| 935 | } | 937 | } |
| 936 | | 938 | |
| 937 | void *__bound_memmove(void *dst, const void *src, size_t size) | 939 | void *__bound_memmove(void *dst, const void *src, size_t size) |
| 938 | { | 940 | { |
| 939 | INCR_COUNT(bound_memmove_count); | 941 | INCR_COUNT(bound_memmove_count); |
| 940 | __bound_check(dst, size); | 942 | __bound_check(dst, size, "memmove"); |
| 941 | __bound_check(src, size); | 943 | __bound_check(src, size, "memmove"); |
| 942 | return memmove(dst, src, size); | 944 | return memmove(dst, src, size); |
| 943 | } | 945 | } |
| 944 | | 946 | |
| 945 | void *__bound_memset(void *dst, int c, size_t size) | 947 | void *__bound_memset(void *dst, int c, size_t size) |
| 946 | { | 948 | { |
| 947 | INCR_COUNT(bound_memset_count); | 949 | INCR_COUNT(bound_memset_count); |
| 948 | __bound_check(dst, size); | 950 | __bound_check(dst, size, "memset"); |
| 949 | return memset(dst, c, size); | 951 | return memset(dst, c, size); |
| 950 | } | 952 | } |
| 951 | | 953 | |
| @@ -957,7 +959,7 @@ int __bound_strlen(const char *s) · 5 unmodified lines |
| 957 | INCR_COUNT(bound_strlen_count); | 959 | INCR_COUNT(bound_strlen_count); |
| 958 | while (*p++); | 960 | while (*p++); |
| 959 | len = (p - s) - 1; | 961 | len = (p - s) - 1; |
| 960 | p = __bound_ptr_indir1((char *)s, len); | 962 | p = __bound_ptr_indir1((char *)s, len, 0, "strlen"); |
| 961 | if (p == INVALID_POINTER) | 963 | if (p == INVALID_POINTER) |
| 962 | bound_error("bad pointer in strlen()"); | 964 | bound_error("bad pointer in strlen()"); |
| 963 | return len; | 965 | return len; |
| @@ -982,8 +984,8 @@ char *__bound_strncpy(char *dst, const char *src, size_t n) · 18 unmodified lines |
| 982 | while (len-- && *p++); | 984 | while (len-- && *p++); |
| 983 | len = p - src; | 985 | len = p - src; |
| 984 | INCR_COUNT(bound_strncpy_count); | 986 | INCR_COUNT(bound_strncpy_count); |
| 985 | __bound_check(dst, len); | 987 | __bound_check(dst, len, "strncpy"); |
| 986 | __bound_check(src, len); | 988 | __bound_check(src, len, "strncpy"); |
| 987 | return strncpy (dst, src, n); | 989 | return strncpy (dst, src, n); |
| 988 | } | 990 | } |
| 989 | | 991 | |
| @@ -997,8 +999,8 @@ int __bound_strcmp(const char *s1, const char *s2) · 7 unmodified lines |
| 997 | u1++; | 999 | u1++; |
| 998 | u2++; | 1000 | u2++; |
| 999 | } | 1001 | } |
| 1000 | __bound_check(s1, ((const char *)u1 - s1) + 1); | 1002 | __bound_check(s1, ((const char *)u1 - s1) + 1, "strcmp"); |
| 1001 | __bound_check(s2, ((const char *)u2 - s2) + 1); | 1003 | __bound_check(s2, ((const char *)u2 - s2) + 1, "strcmp"); |
| 1002 | return (*u1 - *u2); | 1004 | return (*u1 - *u2); |
| 1003 | } | 1005 | } |
| 1004 | | 1006 | |
| @@ -1018,8 +1020,8 @@ int __bound_strncmp(const char *s1, const char *s2, size_t n) · 13 unmodified lines |
| 1018 | } | 1020 | } |
| 1019 | u2++; | 1021 | u2++; |
| 1020 | } while (*u1++); | 1022 | } while (*u1++); |
| 1021 | __bound_check(s1, ((const char *)u1 - s1) + 1); | 1023 | __bound_check(s1, ((const char *)u1 - s1) + 1, "strncmp"); |
| 1022 | __bound_check(s2, ((const char *)u1 - s1) + 1); | 1024 | __bound_check(s2, ((const char *)u1 - s1) + 1, "strncmp"); |
| 1023 | return retval; | 1025 | return retval; |
| 1024 | } | 1026 | } |
| 1025 | | 1027 | |
| @@ -1032,8 +1034,8 @@ char *__bound_strcat(char *dest, const char *src) · 6 unmodified lines |
| 1032 | while (*dest++); | 1034 | while (*dest++); |
| 1033 | dest--; | 1035 | dest--; |
| 1034 | while ((*dest++ = *src++) != 0); | 1036 | while ((*dest++ = *src++) != 0); |
| 1035 | __bound_check(r, dest - r); | 1037 | __bound_check(r, dest - r, "strcat"); |
| 1036 | __bound_check(s, src - s); | 1038 | __bound_check(s, src - s, "strcat"); |
| 1037 | return r; | 1039 | return r; |
| 1038 | } | 1040 | } |
| 1039 | | 1041 | |
| @@ -1049,7 +1051,7 @@ char *__bound_strchr(const char *string, int ch) · 9 unmodified lines |
| 1049 | } | 1051 | } |
| 1050 | s++; | 1052 | s++; |
| 1051 | } | 1053 | } |
| 1052 | __bound_check(string, ((const char *)s - string) + 1); | 1054 | __bound_check(string, ((const char *)s - string) + 1, "strchr"); |
| 1053 | return *s == c ? (char *) s : NULL; | 1055 | return *s == c ? (char *) s : NULL; |
| 1054 | } | 1056 | } |
| 1055 | | 1057 | |
| @@ -1060,7 +1062,7 @@ char *__bound_strdup(const char *s) · 4 unmodified lines |
| 1060 | | 1062 | |
| 1061 | INCR_COUNT(bound_strdup_count); | 1063 | INCR_COUNT(bound_strdup_count); |
| 1062 | while (*p++); | 1064 | while (*p++); |
| 1063 | __bound_check(s, p - s); | 1065 | __bound_check(s, p - s, "strdup"); |
| 1064 | #if MALLOC_REDIR | 1066 | #if MALLOC_REDIR |
| 1065 | new = malloc_redir (p - s); | 1067 | new = malloc_redir (p - s); |
| 1066 | #else | 1068 | #else |
| @@ -1069,7 +1071,7 @@ char *__bound_strdup(const char *s) · 2 unmodified lines |
| 1069 | if (new) { | 1071 | if (new) { |
| 1070 | WAIT_SEM (); | 1072 | WAIT_SEM (); |
| 1071 | tree = splay_insert((size_t)new, p - s, tree); | 1073 | tree = splay_insert((size_t)new, p - s, tree); |
| 1072 | if (tree->start == (size_t) new) { | 1074 | if (tree && tree->start == (size_t) new) { |
| 1073 | tree->type = TCC_TYPE_STRDUP; | 1075 | tree->type = TCC_TYPE_STRDUP; |
| 1074 | } | 1076 | } |
| 1075 | memcpy (new, s, p - s); | 1077 | memcpy (new, s, p - s); |
| @@ -1261,22 +1263,26 @@ static Tree * splay_insert(size_t addr, size_t size, Tree * t) · 185 unmodified lines |
| 1261 | new = (Tree *) malloc (sizeof (Tree)); | 1263 | new = (Tree *) malloc (sizeof (Tree)); |
| 1262 | #endif | 1264 | #endif |
| 1263 | } | 1265 | } |
| 1264 | if (new == NULL) {bound_alloc_error();} | 1266 | if (new == NULL) { |
| 1265 | if (t == NULL) { | 1267 | bound_alloc_error(); |
| 1266 | new->left = new->right = NULL; | 1268 | } |
| 1267 | } else if (compare(addr, t->start, t->size) < 0) { | 1269 | else { |
| 1268 | new->left = t->left; | 1270 | if (t == NULL) { |
| 1269 | new->right = t; | 1271 | new->left = new->right = NULL; |
| 1270 | t->left = NULL; | 1272 | } else if (compare(addr, t->start, t->size) < 0) { |
| 1271 | } else { | 1273 | new->left = t->left; |
| 1272 | new->right = t->right; | 1274 | new->right = t; |
| 1273 | new->left = t; | 1275 | t->left = NULL; |
| 1274 | t->right = NULL; | 1276 | } else { |
| | 1277 | new->right = t->right; |
| | 1278 | new->left = t; |
| | 1279 | t->right = NULL; |
| | 1280 | } |
| | 1281 | new->start = addr; |
| | 1282 | new->size = size; |
| | 1283 | new->type = TCC_TYPE_NONE; |
| | 1284 | new->is_invalid = 0; |
| 1275 | } | 1285 | } |
| 1276 | new->start = addr; | | |
| 1277 | new->size = size; | | |
| 1278 | new->type = TCC_TYPE_NONE; | | |
| 1279 | new->is_invalid = 0; | | |
| 1280 | return new; | 1286 | return new; |
| 1281 | } | 1287 | } |
| 1282 | | 1288 | |