| @@ -221,7 +221,8 @@ static void bound_alloc_error(void) · 220 unmodified lines |
| 221 | 221 | |
| 222 | 222 | /* return '(p + offset)' for pointer arithmetic (a pointer can reach |
| 223 | 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 | 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 | 230 | return p + offset; |
| 230 | 231 | } |
| 231 | 232 | |
| 232 | | − dprintf(stderr, "%s %s: %p 0x%x\n", |
| 233 | | − __FILE__, __FUNCTION__, p, (unsigned)offset); |
| 233 | + dprintf(stderr, "%s %s (%s:%u): %p 0x%x\n", |
| 234 | + __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); |
| 234 | 235 | |
| 235 | 236 | WAIT_SEM (); |
| 236 | 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 | 250 | if (addr <= tree->size) { |
| 250 | 251 | addr += offset; |
| 251 | 252 | if (tree->is_invalid || addr > tree->size) { |
| 252 | | − fprintf(stderr,"%s %s: %p is outside of the region\n", |
| 253 | | − __FILE__, __FUNCTION__, p + offset); |
| 253 | + fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", |
| 254 | + __FILE__, __FUNCTION__, filename, line, p + offset); |
| 254 | 255 | if (never_fatal == 0) { |
| 255 | 256 | POST_SEM (); |
| 256 | 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 | 266 | /* return '(p + offset)' for pointer indirection (the resulting must |
| 266 | 267 | be strictly inside the region */ |
| 267 | | −#define BOUND_PTR_INDIR(dsize) \ |
| 268 | | −void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ |
| 269 | | −{ \ |
| 270 | | − size_t addr = (size_t)p; \ |
| 271 | | − \ |
| 272 | | − if (no_checking) { \ |
| 273 | | − return p + offset; \ |
| 274 | | − } \ |
| 275 | | − dprintf(stderr, "%s %s: %p 0x%x start\n", \ |
| 276 | | − __FILE__, __FUNCTION__, p, (unsigned)offset); \ |
| 277 | | − WAIT_SEM (); \ |
| 278 | | − INCR_COUNT(bound_ptr_indir ## dsize ## _count); \ |
| 279 | | − if (tree) { \ |
| 280 | | − addr -= tree->start; \ |
| 281 | | − if (addr >= tree->size) { \ |
| 282 | | − addr = (size_t)p; \ |
| 283 | | − tree = splay (addr, tree); \ |
| 284 | | − addr -= tree->start; \ |
| 285 | | − } \ |
| 286 | | − if (addr >= tree->size) { \ |
| 287 | | − addr = (size_t)p; \ |
| 288 | | − tree = splay_end (addr, tree); \ |
| 289 | | − addr -= tree->start; \ |
| 290 | | − } \ |
| 291 | | − if (addr <= tree->size) { \ |
| 292 | | − addr += offset + dsize; \ |
| 293 | | − if (tree->is_invalid || addr > tree->size) { \ |
| 294 | | − fprintf(stderr,"%s %s: %p is outside of the region\n", \ |
| 295 | | − __FILE__, __FUNCTION__, p + offset); \ |
| 296 | | − if (never_fatal == 0) { \ |
| 297 | | − POST_SEM (); \ |
| 298 | | − return INVALID_POINTER; /* return an invalid pointer */ \ |
| 299 | | − } \ |
| 300 | | − } \ |
| 301 | | − } \ |
| 302 | | − } \ |
| 303 | | − POST_SEM (); \ |
| 304 | | − return p + offset; \ |
| 268 | +#define BOUND_PTR_INDIR(dsize) \ |
| 269 | +void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \ |
| 270 | + size_t line, const char *filename) \ |
| 271 | +{ \ |
| 272 | + size_t addr = (size_t)p; \ |
| 273 | + \ |
| 274 | + if (no_checking) { \ |
| 275 | + return p + offset; \ |
| 276 | + } \ |
| 277 | + dprintf(stderr, "%s %s (%s:%u): %p 0x%x start\n", \ |
| 278 | + __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); \ |
| 279 | + WAIT_SEM (); \ |
| 280 | + INCR_COUNT(bound_ptr_indir ## dsize ## _count); \ |
| 281 | + if (tree) { \ |
| 282 | + addr -= tree->start; \ |
| 283 | + if (addr >= tree->size) { \ |
| 284 | + addr = (size_t)p; \ |
| 285 | + tree = splay (addr, tree); \ |
| 286 | + addr -= tree->start; \ |
| 287 | + } \ |
| 288 | + if (addr >= tree->size) { \ |
| 289 | + addr = (size_t)p; \ |
| 290 | + tree = splay_end (addr, tree); \ |
| 291 | + addr -= tree->start; \ |
| 292 | + } \ |
| 293 | + if (addr <= tree->size) { \ |
| 294 | + addr += offset + dsize; \ |
| 295 | + if (tree->is_invalid || addr > tree->size) { \ |
| 296 | + fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", \ |
| 297 | + __FILE__, __FUNCTION__, filename, line, p + offset); \ |
| 298 | + if (never_fatal == 0) { \ |
| 299 | + POST_SEM (); \ |
| 300 | + return INVALID_POINTER; /* return an invalid pointer */ \ |
| 301 | + } \ |
| 302 | + } \ |
| 303 | + } \ |
| 304 | + } \ |
| 305 | + POST_SEM (); \ |
| 306 | + return p + offset; \ |
| 305 | 307 | } |
| 306 | 308 | |
| 307 | 309 | BOUND_PTR_INDIR(1) |
| @@ -540,7 +542,7 @@ void __attribute__((destructor)) __bound_exit(void) · 232 unmodified lines |
| 540 | 542 | } |
| 541 | 543 | while (tree) { |
| 542 | 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 | 546 | __FILE__, __FUNCTION__, alloc_type[tree->type], |
| 545 | 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 | 624 | if (ptr) { |
| 623 | 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 | 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 | 668 | dprintf(stderr, "%s, %s (%p, 0x%x)\n", |
| 667 | 669 | __FILE__, __FUNCTION__, ptr, (unsigned)size); |
| 668 | 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 | 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 | 746 | INCR_COUNT(bound_realloc_count); |
| 745 | 747 | if (ptr) { |
| 746 | 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 | 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 | 763 | #endif |
| 762 | 764 | if (ptr) { |
| 763 | 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 | 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 | 802 | WAIT_SEM (); |
| 801 | 803 | INCR_COUNT(bound_calloc_count); |
| 802 | 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 | 806 | tree->type = TCC_TYPE_CALLOC; |
| 805 | 807 | } |
| 806 | 808 | POST_SEM (); |
| @@ -899,13 +901,13 @@ void __bound_new_region(void *p, size_t size) · 92 unmodified lines |
| 899 | 901 | /* some useful checked functions */ |
| 900 | 902 | |
| 901 | 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 | 906 | if (no_checking) |
| 905 | 907 | return; |
| 906 | 908 | if (size == 0) |
| 907 | 909 | return; |
| 908 | | − p = __bound_ptr_add((void *)p, size); |
| 910 | + p = __bound_ptr_add((void *)p, size, 0, function); |
| 909 | 911 | if (p == INVALID_POINTER) |
| 910 | 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 | 917 | void* p; |
| 916 | 918 | |
| 917 | 919 | INCR_COUNT(bound_mempcy_count); |
| 918 | | − __bound_check(dst, size); |
| 919 | | − __bound_check(src, size); |
| 920 | + __bound_check(dst, size, "memcpy"); |
| 921 | + __bound_check(src, size, "memcpy"); |
| 920 | 922 | /* check also region overlap */ |
| 921 | 923 | if (no_checking == 0 && src >= dst && src < dst + size) |
| 922 | 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 | 931 | int __bound_memcmp(const void *s1, const void *s2, size_t size) |
| 930 | 932 | { |
| 931 | 933 | INCR_COUNT(bound_memcmp_count); |
| 932 | | − __bound_check(s1, size); |
| 933 | | − __bound_check(s2, size); |
| 934 | + __bound_check(s1, size, "memcmp"); |
| 935 | + __bound_check(s2, size, "memcmp"); |
| 934 | 936 | return memcmp(s1, s2, size); |
| 935 | 937 | } |
| 936 | 938 | |
| 937 | 939 | void *__bound_memmove(void *dst, const void *src, size_t size) |
| 938 | 940 | { |
| 939 | 941 | INCR_COUNT(bound_memmove_count); |
| 940 | | − __bound_check(dst, size); |
| 941 | | − __bound_check(src, size); |
| 942 | + __bound_check(dst, size, "memmove"); |
| 943 | + __bound_check(src, size, "memmove"); |
| 942 | 944 | return memmove(dst, src, size); |
| 943 | 945 | } |
| 944 | 946 | |
| 945 | 947 | void *__bound_memset(void *dst, int c, size_t size) |
| 946 | 948 | { |
| 947 | 949 | INCR_COUNT(bound_memset_count); |
| 948 | | − __bound_check(dst, size); |
| 950 | + __bound_check(dst, size, "memset"); |
| 949 | 951 | return memset(dst, c, size); |
| 950 | 952 | } |
| 951 | 953 | |
| @@ -957,7 +959,7 @@ int __bound_strlen(const char *s) · 5 unmodified lines |
| 957 | 959 | INCR_COUNT(bound_strlen_count); |
| 958 | 960 | while (*p++); |
| 959 | 961 | len = (p - s) - 1; |
| 960 | | − p = __bound_ptr_indir1((char *)s, len); |
| 962 | + p = __bound_ptr_indir1((char *)s, len, 0, "strlen"); |
| 961 | 963 | if (p == INVALID_POINTER) |
| 962 | 964 | bound_error("bad pointer in strlen()"); |
| 963 | 965 | return len; |
| @@ -982,8 +984,8 @@ char *__bound_strncpy(char *dst, const char *src, size_t n) · 18 unmodified lines |
| 982 | 984 | while (len-- && *p++); |
| 983 | 985 | len = p - src; |
| 984 | 986 | INCR_COUNT(bound_strncpy_count); |
| 985 | | − __bound_check(dst, len); |
| 986 | | − __bound_check(src, len); |
| 987 | + __bound_check(dst, len, "strncpy"); |
| 988 | + __bound_check(src, len, "strncpy"); |
| 987 | 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 | 999 | u1++; |
| 998 | 1000 | u2++; |
| 999 | 1001 | } |
| 1000 | | − __bound_check(s1, ((const char *)u1 - s1) + 1); |
| 1001 | | − __bound_check(s2, ((const char *)u2 - s2) + 1); |
| 1002 | + __bound_check(s1, ((const char *)u1 - s1) + 1, "strcmp"); |
| 1003 | + __bound_check(s2, ((const char *)u2 - s2) + 1, "strcmp"); |
| 1002 | 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 | 1021 | u2++; |
| 1020 | 1022 | } while (*u1++); |
| 1021 | | − __bound_check(s1, ((const char *)u1 - s1) + 1); |
| 1022 | | − __bound_check(s2, ((const char *)u1 - s1) + 1); |
| 1023 | + __bound_check(s1, ((const char *)u1 - s1) + 1, "strncmp"); |
| 1024 | + __bound_check(s2, ((const char *)u1 - s1) + 1, "strncmp"); |
| 1023 | 1025 | return retval; |
| 1024 | 1026 | } |
| 1025 | 1027 | |
| @@ -1032,8 +1034,8 @@ char *__bound_strcat(char *dest, const char *src) · 6 unmodified lines |
| 1032 | 1034 | while (*dest++); |
| 1033 | 1035 | dest--; |
| 1034 | 1036 | while ((*dest++ = *src++) != 0); |
| 1035 | | − __bound_check(r, dest - r); |
| 1036 | | − __bound_check(s, src - s); |
| 1037 | + __bound_check(r, dest - r, "strcat"); |
| 1038 | + __bound_check(s, src - s, "strcat"); |
| 1037 | 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 | 1052 | s++; |
| 1051 | 1053 | } |
| 1052 | | − __bound_check(string, ((const char *)s - string) + 1); |
| 1054 | + __bound_check(string, ((const char *)s - string) + 1, "strchr"); |
| 1053 | 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 | 1063 | INCR_COUNT(bound_strdup_count); |
| 1062 | 1064 | while (*p++); |
| 1063 | | − __bound_check(s, p - s); |
| 1065 | + __bound_check(s, p - s, "strdup"); |
| 1064 | 1066 | #if MALLOC_REDIR |
| 1065 | 1067 | new = malloc_redir (p - s); |
| 1066 | 1068 | #else |
| @@ -1069,7 +1071,7 @@ char *__bound_strdup(const char *s) · 2 unmodified lines |
| 1069 | 1071 | if (new) { |
| 1070 | 1072 | WAIT_SEM (); |
| 1071 | 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 | 1075 | tree->type = TCC_TYPE_STRDUP; |
| 1074 | 1076 | } |
| 1075 | 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 | 1263 | new = (Tree *) malloc (sizeof (Tree)); |
| 1262 | 1264 | #endif |
| 1263 | 1265 | } |
| 1264 | | − if (new == NULL) {bound_alloc_error();} |
| 1265 | | − if (t == NULL) { |
| 1266 | | − new->left = new->right = NULL; |
| 1267 | | − } else if (compare(addr, t->start, t->size) < 0) { |
| 1268 | | − new->left = t->left; |
| 1269 | | − new->right = t; |
| 1270 | | − t->left = NULL; |
| 1271 | | − } else { |
| 1272 | | − new->right = t->right; |
| 1273 | | − new->left = t; |
| 1274 | | − t->right = NULL; |
| 1266 | + if (new == NULL) { |
| 1267 | + bound_alloc_error(); |
| 1268 | + } |
| 1269 | + else { |
| 1270 | + if (t == NULL) { |
| 1271 | + new->left = new->right = NULL; |
| 1272 | + } else if (compare(addr, t->start, t->size) < 0) { |
| 1273 | + new->left = t->left; |
| 1274 | + new->right = t; |
| 1275 | + t->left = 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 | 1286 | return new; |
| 1281 | 1287 | } |
| 1282 | 1288 | |