diff --git a/.gitignore b/.gitignore index ae4965c5..376ea52e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,11 @@ tc1.c error.c i386-gen1.c test.out1 +test.out1b test.out2 +test.out2b test.out3 +test.out3b web.sh memdebug.c bench diff --git a/lib/bcheck.c b/lib/bcheck.c index 5ea2d0bf..00b90fea 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -25,6 +25,7 @@ && !defined(__DragonFly__) && !defined(__OpenBSD__) #include #endif +#include //#define BOUND_DEBUG @@ -94,9 +95,6 @@ static void *saved_realloc_hook; static void *saved_memalign_hook; #endif -/* linker definitions */ -extern char _end; - /* TCC definitions */ extern char __bounds_start; /* start of static bounds table */ /* error message, just for TCC */ @@ -379,9 +377,32 @@ void __bound_init(void) #if !defined(__TINYC__) && defined(CONFIG_TCC_MALLOC_HOOKS) /* malloc zone is also marked invalid. can only use that with - hooks because all libs should use the same malloc. The solution - would be to build a new malloc for tcc. */ - start = (unsigned long)&_end; + * hooks because all libs should use the same malloc. The solution + * would be to build a new malloc for tcc. + * + * usually heap (= malloc zone) comes right after bss, i.e. after _end, but + * not always - either if we are running from under `tcc -b -run`, or if + * address space randomization is turned on(a), heap start will be separated + * from bss end. + * + * So sbrk(0) will be a good approximation for start_brk: + * + * - if we are a separately compiled program, __bound_init() runs early, + * and sbrk(0) should be equal or very near to start_brk(b) (in case other + * constructors malloc something), or + * + * - if we are running from under `tcc -b -run`, sbrk(0) will return + * start of heap portion which is under this program control, and not + * mark as invalid earlier allocated memory. + * + * + * (a) /proc/sys/kernel/randomize_va_space = 2, on Linux; + * usually turned on by default. + * + * (b) on Linux >= v3.3, the alternative is to read + * start_brk from /proc/self/stat + */ + start = (unsigned long)sbrk(0); size = 128 * 0x100000; mark_invalid(start, size); #endif @@ -592,7 +613,7 @@ int __bound_delete_region(void *p) } } /* last page */ - page = get_page(t2_end); + page = get_page(t1_end); e2 = (BoundEntry *)((char *)page + t2_end); for(e=page;estart = 0; diff --git a/tcc.h b/tcc.h index 9f818587..fe870d84 100644 --- a/tcc.h +++ b/tcc.h @@ -1127,7 +1127,8 @@ ST_DATA Sym *local_label_stack; ST_DATA Sym *global_label_stack; ST_DATA Sym *define_stack; ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; -ST_DATA SValue vstack[VSTACK_SIZE], *vtop; +ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop; +#define vstack (__vstack + 1) ST_DATA int rsym, anon_sym, ind, loc; ST_DATA int const_wanted; /* true if constant wanted */ diff --git a/tccgen.c b/tccgen.c index f79da367..b9142d27 100644 --- a/tccgen.c +++ b/tccgen.c @@ -55,7 +55,7 @@ ST_DATA Sym *define_stack; ST_DATA Sym *global_label_stack; ST_DATA Sym *local_label_stack; -ST_DATA SValue vstack[VSTACK_SIZE], *vtop; +ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop; ST_DATA int const_wanted; /* true if constant wanted */ ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ diff --git a/tccpp.c b/tccpp.c index aff5a535..b80c986c 100644 --- a/tccpp.c +++ b/tccpp.c @@ -3041,7 +3041,6 @@ ST_FUNC void preprocess_init(TCCState *s1) s1->ifdef_stack_ptr = s1->ifdef_stack; file->ifdef_stack_ptr = s1->ifdef_stack_ptr; - /* XXX: not ANSI compliant: bound checking says error */ vtop = vstack - 1; s1->pack_stack[0] = 0; s1->pack_stack_ptr = s1->pack_stack; diff --git a/tests/Makefile b/tests/Makefile index da7c3f97..116178f7 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -12,6 +12,9 @@ TESTS = libtest \ test3 \ speedtest \ btest \ + test1b\ + test2b\ + test3b\ weaktest # test4 # this test does not seem to work on any platform @@ -20,6 +23,9 @@ TESTS = libtest \ # bounds-checking is supported only on i386 ifneq ($(ARCH),i386) TESTS := $(filter-out btest,$(TESTS)) + TESTS := $(filter-out test1b,$(TESTS)) + TESTS := $(filter-out test2b,$(TESTS)) + TESTS := $(filter-out test3b,$(TESTS)) endif # these should work too @@ -87,18 +93,33 @@ test1: test.ref $(TCC) -run tcctest.c > test.out1 @if diff -u test.ref test.out1 ; then echo "Auto Test OK"; fi +test1b: test.ref + @echo ------------ $@ ------------ + $(TCC) -b -run tcctest.c > test.out1b + @if diff -u test.ref test.out1b ; then echo "Auto Test OK"; fi + # iterated test2 (compile tcc then compile tcctest.c !) test2: test.ref @echo ------------ $@ ------------ $(TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out2 @if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi +test2b: test.ref ../bcheck.o + @echo ------------ $@ ------------ + $(TCC) -b $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out2b + @if diff -u test.ref test.out2b ; then echo "Auto Test2b OK"; fi + # iterated test3 (compile tcc then compile tcc then compile tcctest.c !) test3: test.ref @echo ------------ $@ ------------ $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out3 @if diff -u test.ref test.out3 ; then echo "Auto Test3 OK"; fi +test3b: test.ref + @echo ------------ $@ ------------ + $(TCC) -b $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out3b + @if diff -u test.ref test.out3b ; then echo "Auto Test3 OK"; fi + # binary output test test4: test.ref @echo ------------ $@ ------------ @@ -190,5 +211,5 @@ cache: tcc_g # clean clean: - rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.gcc \ + rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.gcc \ tcctest[1234] ex? libtcc_test$(EXESUF) tcc_g tcclib.h