tcc failed to run with bounds checking enabled because the functions rt_wait_sem, rt_post_sem and _rt_error where defined twice. This is solved by making them weak in tccrun.c Also a nested lock was present when setting TCC_BOUNDS_PRINT_CALLS=1 This is solved in lib/bt-exe.c by moving lock/unlock code. Also added a testcase in tests/Makefile to test tcc with bounds checking enabled.
Unified · Split
| @@ -18,7 +18,6 @@ void __bt_init(rt_context *p, int is_exe) · 17 unmodified lines | |||
| 18 | __attribute__((weak)) int main(); | 18 | __attribute__((weak)) int main(); |
| 19 | __attribute__((weak)) void __bound_init(void*, int); | 19 | __attribute__((weak)) void __bound_init(void*, int); |
| 20 | 20 | ||
| 21 | WAIT_SEM(&rt_sem); | ||
| 22 | //fprintf(stderr, "__bt_init %d %p %p %p\n", is_exe, p, p->stab_sym, p->bounds_start), fflush(stderr); | 21 | //fprintf(stderr, "__bt_init %d %p %p %p\n", is_exe, p, p->stab_sym, p->bounds_start), fflush(stderr); |
| 23 | 22 | ||
| 24 | /* call __bound_init here due to redirection of sigaction */ | 23 | /* call __bound_init here due to redirection of sigaction */ |
| @@ -27,13 +26,14 @@ void __bt_init(rt_context *p, int is_exe) · 2 unmodified lines | |||
| 27 | __bound_init(p->bounds_start, -1); | 26 | __bound_init(p->bounds_start, -1); |
| 28 | 27 | ||
| 29 | /* add to chain */ | 28 | /* add to chain */ |
| 29 | WAIT_SEM(&rt_sem); | ||
| 30 | p->next = g_rc, g_rc = p; | 30 | p->next = g_rc, g_rc = p; |
| 31 | if (is_exe) { | 31 | if (is_exe) |
| 32 | /* we are the executable (not a dll) */ | 32 | /* we are the executable (not a dll) */ |
| 33 | p->top_func = main; | 33 | p->top_func = main; |
| 34 | set_exception_handler(); | ||
| 35 | } | ||
| 36 | POST_SEM(&rt_sem); | 34 | POST_SEM(&rt_sem); |
| 35 | if (is_exe) | ||
| 36 | set_exception_handler(); | ||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | __declspec(dllexport) | 39 | __declspec(dllexport) |
| @@ -42,13 +42,13 @@ void __bt_exit(rt_context *p) · 2 unmodified lines | |||
| 42 | struct rt_context *rc, **pp; | 42 | struct rt_context *rc, **pp; |
| 43 | __attribute__((weak)) void __bound_exit_dll(void*); | 43 | __attribute__((weak)) void __bound_exit_dll(void*); |
| 44 | 44 | ||
| 45 | WAIT_SEM(&rt_sem); | ||
| 46 | //fprintf(stderr, "__bt_exit %d %p\n", !!p->top_func, p); | 45 | //fprintf(stderr, "__bt_exit %d %p\n", !!p->top_func, p); |
| 47 | 46 | ||
| 48 | if (p->bounds_start) | 47 | if (p->bounds_start) |
| 49 | __bound_exit_dll(p->bounds_start); | 48 | __bound_exit_dll(p->bounds_start); |
| 50 | 49 | ||
| 51 | /* remove from chain */ | 50 | /* remove from chain */ |
| 51 | WAIT_SEM(&rt_sem); | ||
| 52 | for (pp = &g_rc; rc = *pp, rc; pp = &rc->next) | 52 | for (pp = &g_rc; rc = *pp, rc; pp = &rc->next) |
| 53 | if (rc == p) { | 53 | if (rc == p) { |
| 54 | *pp = rc->next; | 54 | *pp = rc->next; |
| @@ -66,9 +66,15 @@ TCC_SEM(static rt_sem); · 65 unmodified lines | |||
| 66 | static int signal_set; | 66 | static int signal_set; |
| 67 | static void set_exception_handler(void); | 67 | static void set_exception_handler(void); |
| 68 | 68 | ||
| 69 | int _rt_error(rt_frame *f, const char *msg, const char *fmt, va_list ap); | 69 | #ifdef _WIN32 |
| 70 | void rt_wait_sem(void) { WAIT_SEM(&rt_sem); } | 70 | #define ATTR_WEAK |
| 71 | void rt_post_sem(void) { POST_SEM(&rt_sem); } | 71 | #else |
| 72 | #define ATTR_WEAK __attribute__((weak)) | ||
| 73 | #endif | ||
| 74 | int ATTR_WEAK _rt_error(rt_frame *f, const char *msg, const char *fmt, va_list ap); | ||
| 75 | void ATTR_WEAK rt_wait_sem(void) { WAIT_SEM(&rt_sem); } | ||
| 76 | void ATTR_WEAK rt_post_sem(void) { POST_SEM(&rt_sem); } | ||
| 77 | #undef ATTR_WEAK | ||
| 72 | #endif /* def CONFIG_TCC_BACKTRACE */ | 78 | #endif /* def CONFIG_TCC_BACKTRACE */ |
| 73 | 79 | ||
| 74 | /* handle exit/atexit for tcc_run() -- thread-unsafe */ | 80 | /* handle exit/atexit for tcc_run() -- thread-unsafe */ |
| @@ -28,6 +28,9 @@ TESTS = \ · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | ifneq ($(CONFIG_bcheck),no) | 29 | ifneq ($(CONFIG_bcheck),no) |
| 30 | TESTS += btest test1b | 30 | TESTS += btest test1b |
| 31 | ifndef CONFIG_WIN32 | ||
| 32 | TESTS += tccb | ||
| 33 | endif | ||
| 31 | endif | 34 | endif |
| 32 | ifeq ($(CONFIG_dll),no) | 35 | ifeq ($(CONFIG_dll),no) |
| 33 | TESTS := $(filter-out dlltest, $(TESTS)) | 36 | TESTS := $(filter-out dlltest, $(TESTS)) |
| @@ -198,6 +201,13 @@ btest: boundtest.c · 164 unmodified lines | |||
| 198 | done ;\ | 201 | done ;\ |
| 199 | echo Bound test OK | 202 | echo Bound test OK |
| 200 | 203 | ||
| 204 | tccb: | ||
| 205 | @echo ------------ $@ ------------ | ||
| 206 | $(TCC) -b $(TOPSRC)/tcc.c $(TCCFLAGS) $(NATIVE_DEFINES) -o v1-tcc$(EXESUF) | ||
| 207 | mv v1-tcc$(EXESUF) v2-tcc$(EXESUF) | ||
| 208 | ./v2-tcc$(EXESUF) -b $(TOPSRC)/tcc.c $(TCCFLAGS) $(NATIVE_DEFINES) -o v1-tcc$(EXESUF) | ||
| 209 | cmp -s v1-tcc$(EXESUF) v2-tcc$(EXESUF) && echo "Bound-Test tcc OK" | ||
| 210 | |||
| 201 | # speed test | 211 | # speed test |
| 202 | speedtest: ex2 ex3 | 212 | speedtest: ex2 ex3 |
| 203 | @echo ------------ $@ ------------ | 213 | @echo ------------ $@ ------------ |
| @@ -260,7 +270,7 @@ vla_test-run: vla_test$(EXESUF) · 56 unmodified lines | |||
| 260 | @echo ------------ $@ ------------ | 270 | @echo ------------ $@ ------------ |
| 261 | ./vla_test$(EXESUF) | 271 | ./vla_test$(EXESUF) |
| 262 | 272 | ||
| 263 | .PHONY: abitest vla_test | 273 | .PHONY: abitest vla_test tccb |
| 264 | 274 | ||
| 265 | asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c | 275 | asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c |
| 266 | $(TCC) -o $@ $^ | 276 | $(TCC) -o $@ $^ |