On this weekend a thought came to me again that tinycc could be used for scripting. Only its bounds-checking mode turned out to be broken, which is a pity because bounds-checking is sometimes handy especially for quickly written scripts. Since tinycc is one of those small beautiful things, seldomly happening in our times, I couldn't resist trying to fix it. Thanks, Kirill * bcheck: Now btest pass! lib/bcheck: Prevent __bound_local_new / __bound_local_delete from being miscompiled lib/bcheck: Prevent libc_malloc/libc_free etc from being miscompiled
Unified · Split
| @@ -208,25 +208,11 @@ BOUND_PTR_INDIR(8) · 207 unmodified lines | |||
| 208 | BOUND_PTR_INDIR(12) | 208 | BOUND_PTR_INDIR(12) |
| 209 | BOUND_PTR_INDIR(16) | 209 | BOUND_PTR_INDIR(16) |
| 210 | 210 | ||
| 211 | #ifdef __i386__ | ||
| 212 | /* return the frame pointer of the caller */ | 211 | /* return the frame pointer of the caller */ |
| 213 | #define GET_CALLER_FP(fp)\ | 212 | #define GET_CALLER_FP(fp)\ |
| 214 | {\ | 213 | {\ |
| 215 | unsigned long *fp1;\ | 214 | fp = (unsigned long)__builtin_frame_address(1);\ |
| 216 | __asm__ __volatile__ ("movl %%ebp,%0" :"=g" (fp1));\ | ||
| 217 | fp = fp1[0];\ | ||
| 218 | } | 215 | } |
| 219 | #elif defined(__x86_64__) | ||
| 220 | /* TCC always creates %rbp frames also on x86_64, so use them. */ | ||
| 221 | #define GET_CALLER_FP(fp)\ | ||
| 222 | {\ | ||
| 223 | unsigned long *fp1;\ | ||
| 224 | __asm__ __volatile__ ("movq %%rbp,%0" :"=g" (fp1));\ | ||
| 225 | fp = fp1[0];\ | ||
| 226 | } | ||
| 227 | #else | ||
| 228 | #error put code to extract the calling frame pointer | ||
| 229 | #endif | ||
| 230 | 216 | ||
| 231 | /* called when entering a function to add all the local regions */ | 217 | /* called when entering a function to add all the local regions */ |
| 232 | void FASTCALL __bound_local_new(void *p1) | 218 | void FASTCALL __bound_local_new(void *p1) |
| @@ -638,6 +624,9 @@ static unsigned long get_region_size(void *p) · 405 unmodified lines | |||
| 638 | 624 | ||
| 639 | /* patched memory functions */ | 625 | /* patched memory functions */ |
| 640 | 626 | ||
| 627 | /* force compiler to perform stores coded up to this point */ | ||
| 628 | #define barrier() __asm__ __volatile__ ("": : : "memory") | ||
| 629 | |||
| 641 | static void install_malloc_hooks(void) | 630 | static void install_malloc_hooks(void) |
| 642 | { | 631 | { |
| 643 | #ifdef CONFIG_TCC_MALLOC_HOOKS | 632 | #ifdef CONFIG_TCC_MALLOC_HOOKS |
| @@ -649,6 +638,8 @@ static void install_malloc_hooks(void) · 5 unmodified lines | |||
| 649 | __free_hook = __bound_free; | 638 | __free_hook = __bound_free; |
| 650 | __realloc_hook = __bound_realloc; | 639 | __realloc_hook = __bound_realloc; |
| 651 | __memalign_hook = __bound_memalign; | 640 | __memalign_hook = __bound_memalign; |
| 641 | |||
| 642 | barrier(); | ||
| 652 | #endif | 643 | #endif |
| 653 | } | 644 | } |
| 654 | 645 | ||
| @@ -659,6 +650,8 @@ static void restore_malloc_hooks(void) · 4 unmodified lines | |||
| 659 | __free_hook = saved_free_hook; | 650 | __free_hook = saved_free_hook; |
| 660 | __realloc_hook = saved_realloc_hook; | 651 | __realloc_hook = saved_realloc_hook; |
| 661 | __memalign_hook = saved_memalign_hook; | 652 | __memalign_hook = saved_memalign_hook; |
| 653 | |||
| 654 | barrier(); | ||
| 662 | #endif | 655 | #endif |
| 663 | } | 656 | } |
| 664 | 657 | ||
| @@ -22,7 +22,6 @@ TESTS = libtest \ · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | # some tests do not pass on all platforms, remove them for now | 23 | # some tests do not pass on all platforms, remove them for now |
| 24 | ifeq ($(TARGETOS),Linux) | 24 | ifeq ($(TARGETOS),Linux) |
| 25 | TESTS := $(filter-out btest,$(TESTS)) | ||
| 26 | TESTS := $(filter-out weaktest,$(TESTS)) | 25 | TESTS := $(filter-out weaktest,$(TESTS)) |
| 27 | endif | 26 | endif |
| 28 | ifeq ($(TARGETOS),Darwin) | 27 | ifeq ($(TARGETOS),Darwin) |