Changeset 331 for EcnlProtoTool/trunk/tcc-0.9.27/lib/bcheck.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/tcc-0.9.27
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/tcc-0.9.27/lib/bcheck.c
r321 r331 22 22 #include <stdarg.h> 23 23 #include <string.h> 24 #if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) \ 25 && !defined(__DragonFly__) && !defined(__OpenBSD__) 24 25 #if !defined(__FreeBSD__) \ 26 && !defined(__FreeBSD_kernel__) \ 27 && !defined(__DragonFly__) \ 28 && !defined(__OpenBSD__) \ 29 && !defined(__NetBSD__) 26 30 #include <malloc.h> 27 31 #endif 32 28 33 #if !defined(_WIN32) 29 34 #include <unistd.h> 30 35 #endif 31 36 32 //#define BOUND_DEBUG 37 /* #define BOUND_DEBUG */ 38 39 #ifdef BOUND_DEBUG 40 #define dprintf(a...) fprintf(a) 41 #else 42 #define dprintf(a...) 43 #endif 33 44 34 45 /* define so that bound array is static (faster, but use memory if 35 46 bound checking not used) */ 36 / /#define BOUND_STATIC47 /* #define BOUND_STATIC */ 37 48 38 49 /* use malloc hooks. Currently the code cannot be reliable if no hooks */ … … 40 51 #define HAVE_MEMALIGN 41 52 42 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \ 43 || defined(__DragonFly__) || defined(__dietlibc__) \ 44 || defined(__UCLIBC__) || defined(__OpenBSD__) \ 45 || defined(_WIN32) || defined(TCC_UCLIBC) 46 #warning Bound checking does not support malloc (etc.) in this environment. 53 #if defined(__FreeBSD__) \ 54 || defined(__FreeBSD_kernel__) \ 55 || defined(__DragonFly__) \ 56 || defined(__OpenBSD__) \ 57 || defined(__NetBSD__) \ 58 || defined(__dietlibc__) \ 59 || defined(_WIN32) 60 //#warning Bound checking does not support malloc (etc.) in this environment. 47 61 #undef CONFIG_TCC_MALLOC_HOOKS 48 62 #undef HAVE_MEMALIGN … … 51 65 #define BOUND_T1_BITS 13 52 66 #define BOUND_T2_BITS 11 53 #define BOUND_T3_BITS ( 32- BOUND_T1_BITS - BOUND_T2_BITS)54 55 #define BOUND_T1_SIZE (1 << BOUND_T1_BITS) 56 #define BOUND_T 2_SIZE (1 << BOUND_T2_BITS)57 #define BOUND_T 3_SIZE (1 << BOUND_T3_BITS)58 #define BOUND_ E_BITS 467 #define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS) 68 #define BOUND_E_BITS (sizeof(size_t)) 69 70 #define BOUND_T1_SIZE ((size_t)1 << BOUND_T1_BITS) 71 #define BOUND_T2_SIZE ((size_t)1 << BOUND_T2_BITS) 72 #define BOUND_T3_SIZE ((size_t)1 << BOUND_T3_BITS) 59 73 60 74 #define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS) 61 #define BOUND_T23_SIZE ( 1 << BOUND_T23_BITS)75 #define BOUND_T23_SIZE ((size_t)1 << BOUND_T23_BITS) 62 76 63 77 … … 65 79 #define INVALID_POINTER ((void *)(-2)) 66 80 /* size of an empty region */ 67 #define EMPTY_SIZE 0xffffffff81 #define EMPTY_SIZE ((size_t)(-1)) 68 82 /* size of an invalid region */ 69 83 #define INVALID_SIZE 0 70 84 71 85 typedef struct BoundEntry { 72 unsigned longstart;73 unsigned longsize;86 size_t start; 87 size_t size; 74 88 struct BoundEntry *next; 75 unsigned longis_invalid; /* true if pointers outside region are invalid */89 size_t is_invalid; /* true if pointers outside region are invalid */ 76 90 } BoundEntry; 77 91 78 92 /* external interface */ 79 93 void __bound_init(void); 80 void __bound_new_region(void *p, unsigned longsize);94 void __bound_new_region(void *p, size_t size); 81 95 int __bound_delete_region(void *p); 82 96 97 #ifdef __attribute__ 98 /* an __attribute__ macro is defined in the system headers */ 99 #undef __attribute__ 100 #endif 83 101 #define FASTCALL __attribute__((regparm(3))) 84 102 … … 105 123 106 124 /* runtime error output */ 107 extern void rt_error( unsigned longpc, const char *fmt, ...);125 extern void rt_error(size_t pc, const char *fmt, ...); 108 126 109 127 #ifdef BOUND_STATIC … … 117 135 static BoundEntry *__bound_find_region(BoundEntry *e1, void *p) 118 136 { 119 unsigned longaddr, tmp;137 size_t addr, tmp; 120 138 BoundEntry *e; 121 139 122 140 e = e1; 123 141 while (e != NULL) { 124 addr = ( unsigned long)p;142 addr = (size_t)p; 125 143 addr -= e->start; 126 144 if (addr <= e->size) { … … 147 165 { 148 166 __bound_error_msg = fmt; 149 *(int *)0 = 0; /* force a runtime error */ 167 fprintf(stderr,"%s %s: %s\n", __FILE__, __FUNCTION__, fmt); 168 *(void **)0 = 0; /* force a runtime error */ 150 169 } 151 170 … … 157 176 /* return '(p + offset)' for pointer arithmetic (a pointer can reach 158 177 the end of a region in this case */ 159 void * FASTCALL __bound_ptr_add(void *p, int offset)160 { 161 unsigned long addr = (unsigned long)p;178 void * FASTCALL __bound_ptr_add(void *p, size_t offset) 179 { 180 size_t addr = (size_t)p; 162 181 BoundEntry *e; 163 #if defined(BOUND_DEBUG) 164 printf("add: 0x%x %d\n", (int)p, offset); 165 #endif 182 183 dprintf(stderr, "%s %s: %p %x\n", 184 __FILE__, __FUNCTION__, p, (unsigned)offset); 185 186 __bound_init(); 166 187 167 188 e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; … … 172 193 if (addr > e->size) { 173 194 e = __bound_find_region(e, p); 174 addr = ( unsigned long)p - e->start;195 addr = (size_t)p - e->start; 175 196 } 176 197 addr += offset; 177 if (addr > e->size) 198 if (addr >= e->size) { 199 fprintf(stderr,"%s %s: %p is outside of the region\n", 200 __FILE__, __FUNCTION__, p + offset); 178 201 return INVALID_POINTER; /* return an invalid pointer */ 202 } 179 203 return p + offset; 180 204 } … … 183 207 be strictly inside the region */ 184 208 #define BOUND_PTR_INDIR(dsize) \ 185 void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset)\209 void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ 186 210 { \ 187 unsigned long addr = (unsigned long)p;\211 size_t addr = (size_t)p; \ 188 212 BoundEntry *e; \ 189 213 \ 214 dprintf(stderr, "%s %s: %p %x start\n", \ 215 __FILE__, __FUNCTION__, p, (unsigned)offset); \ 216 \ 217 __bound_init(); \ 190 218 e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \ 191 219 e = (BoundEntry *)((char *)e + \ … … 195 223 if (addr > e->size) { \ 196 224 e = __bound_find_region(e, p); \ 197 addr = ( unsigned long)p - e->start;\225 addr = (size_t)p - e->start; \ 198 226 } \ 199 227 addr += offset + dsize; \ 200 if (addr > e->size) \ 228 if (addr > e->size) { \ 229 fprintf(stderr,"%s %s: %p is outside of the region\n", \ 230 __FILE__, __FUNCTION__, p + offset); \ 201 231 return INVALID_POINTER; /* return an invalid pointer */ \ 232 } \ 233 dprintf(stderr, "%s %s: return p+offset = %p\n", \ 234 __FILE__, __FUNCTION__, p + offset); \ 202 235 return p + offset; \ 203 236 } … … 210 243 BOUND_PTR_INDIR(16) 211 244 245 #if defined(__GNUC__) && (__GNUC__ >= 6) 246 /* 247 * At least gcc 6.2 complains when __builtin_frame_address is used with 248 * nonzero argument. 249 */ 250 #pragma GCC diagnostic push 251 #pragma GCC diagnostic ignored "-Wframe-address" 252 #endif 253 212 254 /* return the frame pointer of the caller */ 213 255 #define GET_CALLER_FP(fp)\ 214 256 {\ 215 fp = ( unsigned long)__builtin_frame_address(1);\257 fp = (size_t)__builtin_frame_address(1);\ 216 258 } 217 259 … … 219 261 void FASTCALL __bound_local_new(void *p1) 220 262 { 221 unsigned long addr, size, fp, *p = p1; 263 size_t addr, size, fp, *p = p1; 264 265 dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p); 222 266 GET_CALLER_FP(fp); 223 267 for(;;) { … … 230 274 __bound_new_region((void *)addr, size); 231 275 } 276 dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); 232 277 } 233 278 … … 235 280 void FASTCALL __bound_local_delete(void *p1) 236 281 { 237 unsigned longaddr, fp, *p = p1;282 size_t addr, fp, *p = p1; 238 283 GET_CALLER_FP(fp); 239 284 for(;;) { … … 247 292 } 248 293 294 #if defined(__GNUC__) && (__GNUC__ >= 6) 295 #pragma GCC diagnostic pop 296 #endif 297 249 298 static BoundEntry *__bound_new_page(void) 250 299 { 251 300 BoundEntry *page; 252 int i;301 size_t i; 253 302 254 303 page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE); … … 278 327 } 279 328 280 static inline BoundEntry *get_page(int index)329 static BoundEntry *get_page(size_t index) 281 330 { 282 331 BoundEntry *page; 283 332 page = __bound_t1[index]; 284 if ( page == __bound_empty_t2 || page == __bound_invalid_t2) {333 if (!page || page == __bound_empty_t2 || page == __bound_invalid_t2) { 285 334 /* create a new page if necessary */ 286 335 page = __bound_new_page(); … … 291 340 292 341 /* mark a region as being invalid (can only be used during init) */ 293 static void mark_invalid( unsigned long addr, unsigned longsize)294 { 295 unsigned longstart, end;342 static void mark_invalid(size_t addr, size_t size) 343 { 344 size_t start, end; 296 345 BoundEntry *page; 297 int t1_start, t1_end, i, j, t2_start, t2_end;346 size_t t1_start, t1_end, i, j, t2_start, t2_end; 298 347 299 348 start = addr; … … 307 356 308 357 #if 0 309 printf("mark_invalid: start = %x %x\n", t2_start, t2_end);358 dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end); 310 359 #endif 311 360 … … 346 395 void __bound_init(void) 347 396 { 348 int i;397 size_t i; 349 398 BoundEntry *page; 350 unsigned long start, size; 351 int *p; 399 size_t start, size; 400 size_t *p; 401 402 static int inited; 403 if (inited) 404 return; 405 406 inited = 1; 407 408 dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__); 352 409 353 410 /* save malloc hooks and install bound check hooks */ … … 375 432 376 433 /* invalid pointer zone */ 377 start = ( unsigned long)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);434 start = (size_t)INVALID_POINTER & ~(BOUND_T23_SIZE - 1); 378 435 size = BOUND_T23_SIZE; 379 436 mark_invalid(start, size); … … 406 463 * start_brk from /proc/self/stat 407 464 */ 408 start = ( unsigned long)sbrk(0);465 start = (size_t)sbrk(0); 409 466 size = 128 * 0x100000; 410 467 mark_invalid(start, size); … … 412 469 413 470 /* add all static bound check values */ 414 p = ( int *)&__bounds_start;471 p = (size_t *)&__bounds_start; 415 472 while (p[0] != 0) { 416 473 __bound_new_region((void *)p[0], p[1]); 417 474 p += 2; 418 475 } 476 477 dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__); 478 } 479 480 void __bound_main_arg(void **p) 481 { 482 void *start = p; 483 while (*p++); 484 485 dprintf(stderr, "%s, %s calling __bound_new_region(%p %x)\n", 486 __FILE__, __FUNCTION__, start, (unsigned)((void *)p - start)); 487 488 __bound_new_region(start, (void *) p - start); 419 489 } 420 490 421 491 void __bound_exit(void) 422 492 { 493 dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__); 423 494 restore_malloc_hooks(); 424 495 } 425 496 426 497 static inline void add_region(BoundEntry *e, 427 unsigned long start, unsigned longsize)498 size_t start, size_t size) 428 499 { 429 500 BoundEntry *e1; … … 445 516 446 517 /* create a new region. It should not already exist in the region list */ 447 void __bound_new_region(void *p, unsigned longsize)448 { 449 unsigned longstart, end;518 void __bound_new_region(void *p, size_t size) 519 { 520 size_t start, end; 450 521 BoundEntry *page, *e, *e2; 451 int t1_start, t1_end, i, t2_start, t2_end; 452 453 start = (unsigned long)p; 522 size_t t1_start, t1_end, i, t2_start, t2_end; 523 524 dprintf(stderr, "%s, %s(%p, %x) start\n", 525 __FILE__, __FUNCTION__, p, (unsigned)size); 526 527 __bound_init(); 528 529 start = (size_t)p; 454 530 end = start + size; 455 531 t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); … … 462 538 t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & 463 539 ((BOUND_T2_SIZE - 1) << BOUND_E_BITS); 464 #ifdef BOUND_DEBUG 465 printf("new %lx %lx %x %x %x %x\n", 466 start, end, t1_start, t1_end, t2_start, t2_end); 467 #endif 540 468 541 469 542 e = (BoundEntry *)((char *)page + t2_start); … … 507 580 add_region(e, start, size); 508 581 } 582 583 dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); 509 584 } 510 585 511 586 /* delete a region */ 512 static inline void delete_region(BoundEntry *e, 513 void *p, unsigned long empty_size) 514 { 515 unsigned long addr; 587 static inline void delete_region(BoundEntry *e, void *p, size_t empty_size) 588 { 589 size_t addr; 516 590 BoundEntry *e1; 517 591 518 addr = ( unsigned long)p;592 addr = (size_t)p; 519 593 addr -= e->start; 520 594 if (addr <= e->size) { … … 540 614 if (e == NULL) 541 615 break; 542 addr = ( unsigned long)p - e->start;616 addr = (size_t)p - e->start; 543 617 if (addr <= e->size) { 544 618 /* found: remove entry */ … … 555 629 int __bound_delete_region(void *p) 556 630 { 557 unsigned longstart, end, addr, size, empty_size;631 size_t start, end, addr, size, empty_size; 558 632 BoundEntry *page, *e, *e2; 559 int t1_start, t1_end, t2_start, t2_end, i; 560 561 start = (unsigned long)p; 633 size_t t1_start, t1_end, t2_start, t2_end, i; 634 635 dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__); 636 637 __bound_init(); 638 639 start = (size_t)p; 562 640 t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); 563 641 t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & … … 571 649 e = __bound_find_region(e, p); 572 650 /* test if invalid region */ 573 if (e->size == EMPTY_SIZE || ( unsigned long)p != e->start)651 if (e->size == EMPTY_SIZE || (size_t)p != e->start) 574 652 return -1; 575 653 /* compute the size we put in invalid regions */ … … 625 703 delete_region(e, p, empty_size); 626 704 } 705 706 dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__); 707 627 708 return 0; 628 709 } 629 710 630 711 /* return the size of the region starting at p, or EMPTY_SIZE if non 631 exist ant region. */632 static unsigned longget_region_size(void *p)633 { 634 unsigned long addr = (unsigned long)p;712 existent region. */ 713 static size_t get_region_size(void *p) 714 { 715 size_t addr = (size_t)p; 635 716 BoundEntry *e; 636 717 … … 642 723 if (addr > e->size) 643 724 e = __bound_find_region(e, p); 644 if (e->start != ( unsigned long)p)725 if (e->start != (size_t)p) 645 726 return EMPTY_SIZE; 646 727 return e->size; … … 710 791 if (!ptr) 711 792 return NULL; 793 794 dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n", 795 __FILE__, __FUNCTION__, ptr, (unsigned)size); 796 712 797 __bound_new_region(ptr, size); 713 798 return ptr; … … 739 824 if (!ptr) 740 825 return NULL; 826 827 dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n", 828 __FILE__, __FUNCTION__, ptr, (unsigned)size); 829 741 830 __bound_new_region(ptr, size); 742 831 return ptr; … … 756 845 { 757 846 void *ptr1; 758 int old_size;847 size_t old_size; 759 848 760 849 if (size == 0) { … … 791 880 { 792 881 BoundEntry *page, *e; 793 int i, j;794 795 printf("region dump:\n");882 size_t i, j; 883 884 fprintf(stderr, "region dump:\n"); 796 885 for(i=0;i<BOUND_T1_SIZE;i++) { 797 886 page = __bound_t1[i]; … … 800 889 /* do not print invalid or empty entries */ 801 890 if (e->size != EMPTY_SIZE && e->start != 0) { 802 printf("%08x:",891 fprintf(stderr, "%08x:", 803 892 (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + 804 893 (j << BOUND_T3_BITS)); 805 894 do { 806 printf(" %08lx:%08lx", e->start, e->start + e->size);895 fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size); 807 896 e = e->next; 808 897 } while (e != NULL); 809 printf("\n");898 fprintf(stderr, "\n"); 810 899 } 811 900 } … … 821 910 if (size == 0) 822 911 return; 823 p = __bound_ptr_add((void *)p, size );912 p = __bound_ptr_add((void *)p, size - 1); 824 913 if (p == INVALID_POINTER) 825 914 bound_error("invalid pointer"); … … 828 917 void *__bound_memcpy(void *dst, const void *src, size_t size) 829 918 { 919 void* p; 920 921 dprintf(stderr, "%s %s: start, dst=%p src=%p size=%x\n", 922 __FILE__, __FUNCTION__, dst, src, (unsigned)size); 923 830 924 __bound_check(dst, size); 831 925 __bound_check(src, size); … … 833 927 if (src >= dst && src < dst + size) 834 928 bound_error("overlapping regions in memcpy()"); 835 return memcpy(dst, src, size); 929 930 p = memcpy(dst, src, size); 931 932 dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p); 933 return p; 836 934 } 837 935 … … 853 951 { 854 952 const char *p; 855 int len;953 size_t len; 856 954 857 955 len = 0; … … 869 967 char *__bound_strcpy(char *dst, const char *src) 870 968 { 871 int len; 969 size_t len; 970 void *p; 971 972 dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n", 973 __FILE__, __FUNCTION__, dst, src); 872 974 len = __bound_strlen(src); 873 return __bound_memcpy(dst, src, len + 1); 874 } 875 975 p = __bound_memcpy(dst, src, len + 1); 976 dprintf(stderr, "%s %s: strcpy end, p = %p\n", 977 __FILE__, __FUNCTION__, p); 978 return p; 979 }
Note:
See TracChangeset
for help on using the changeset viewer.