History

Repair bounds-checking more, this time `tcc -b -run tcc.c -run tcc.c -run tcctest.c` works

Hello up there. On the list Grischka made a point that we can't recommend using -b as long as tcc -b tcc.c doesn't produce anything useful. Now it does, so please don't treat -b mode as second class citizen anymore. Thanks, Kirill * bcheck2: tests: Add tests for compile/run tcc.c with `tcc -b` then compile tcc.c again, then run tcctest.c lib/bcheck: Fix code typo in __bound_delete_region() lib/bcheck: Don't assume heap goes right after bss Make tcc work after self-compiling with bounds-check enabled

Kirill Smelkov committed 13 years ago

Commit a55ecf62 parents c4a18f4 031ff876 files · +56 −11Browse files

Unified · Split

6 files
  1. .gitignore +3 −0
  2. lib/bcheck.c +28 −7
  3. tcc.h +2 −1
  4. tccgen.c +1 −1
  5. tccpp.c +0 −1
  6. tests/Makefile +22 −1
.gitignore+3−0
@@ -11,8 +11,11 @@ tc1.c · 10 unmodified lines
1111 error.c
1212 i386-gen1.c
1313 test.out1
14+test.out1b
1415 test.out2
16+test.out2b
1517 test.out3
18+test.out3b
1619 web.sh
1720 memdebug.c
1821 bench
lib/bcheck.c+28−7
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 && !defined(__DragonFly__) && !defined(__OpenBSD__)
2626 #include <malloc.h>
2727 #endif
28+#include <unistd.h>
2829
2930 //#define BOUND_DEBUG
3031
@@ -94,9 +95,6 @@ static void *saved_realloc_hook; · 63 unmodified lines
9495 static void *saved_memalign_hook;
9596 #endif
9697
97−/* linker definitions */
98−extern char _end;
99−
10098 /* TCC definitions */
10199 extern char __bounds_start; /* start of static bounds table */
102100 /* error message, just for TCC */
@@ -379,9 +377,32 @@ void __bound_init(void) · 276 unmodified lines
379377
380378 #if !defined(__TINYC__) && defined(CONFIG_TCC_MALLOC_HOOKS)
381379 /* malloc zone is also marked invalid. can only use that with
382− hooks because all libs should use the same malloc. The solution
383− would be to build a new malloc for tcc. */
384− start = (unsigned long)&_end;
380+ * hooks because all libs should use the same malloc. The solution
381+ * would be to build a new malloc for tcc.
382+ *
383+ * usually heap (= malloc zone) comes right after bss, i.e. after _end, but
384+ * not always - either if we are running from under `tcc -b -run`, or if
385+ * address space randomization is turned on(a), heap start will be separated
386+ * from bss end.
387+ *
388+ * So sbrk(0) will be a good approximation for start_brk:
389+ *
390+ * - if we are a separately compiled program, __bound_init() runs early,
391+ * and sbrk(0) should be equal or very near to start_brk(b) (in case other
392+ * constructors malloc something), or
393+ *
394+ * - if we are running from under `tcc -b -run`, sbrk(0) will return
395+ * start of heap portion which is under this program control, and not
396+ * mark as invalid earlier allocated memory.
397+ *
398+ *
399+ * (a) /proc/sys/kernel/randomize_va_space = 2, on Linux;
400+ * usually turned on by default.
401+ *
402+ * (b) on Linux >= v3.3, the alternative is to read
403+ * start_brk from /proc/self/stat
404+ */
405+ start = (unsigned long)sbrk(0);
385406 size = 128 * 0x100000;
386407 mark_invalid(start, size);
387408 #endif
@@ -592,7 +613,7 @@ int __bound_delete_region(void *p) · 204 unmodified lines
592613 }
593614 }
594615 /* last page */
595− page = get_page(t2_end);
616+ page = get_page(t1_end);
596617 e2 = (BoundEntry *)((char *)page + t2_end);
597618 for(e=page;e<e2;e++) {
598619 e->start = 0;
tcc.h+2−1
@@ -1127,7 +1127,8 @@ ST_DATA Sym *local_label_stack; · 1126 unmodified lines
11271127 ST_DATA Sym *global_label_stack;
11281128 ST_DATA Sym *define_stack;
11291129 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
1130−ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
1130+ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop;
1131+#define vstack (__vstack + 1)
11311132 ST_DATA int rsym, anon_sym, ind, loc;
11321133
11331134 ST_DATA int const_wanted; /* true if constant wanted */
tccgen.c+1−1
@@ -55,7 +55,7 @@ ST_DATA Sym *define_stack; · 54 unmodified lines
5555 ST_DATA Sym *global_label_stack;
5656 ST_DATA Sym *local_label_stack;
5757
58−ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
58+ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
5959
6060 ST_DATA int const_wanted; /* true if constant wanted */
6161 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
tccpp.c+0−1
@@ -3041,7 +3041,6 @@ ST_FUNC void preprocess_init(TCCState *s1) · 3040 unmodified lines
30413041 s1->ifdef_stack_ptr = s1->ifdef_stack;
30423042 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
30433043
3044− /* XXX: not ANSI compliant: bound checking says error */
30453044 vtop = vstack - 1;
30463045 s1->pack_stack[0] = 0;
30473046 s1->pack_stack_ptr = s1->pack_stack;
tests/Makefile+22−1
@@ -12,6 +12,9 @@ TESTS = libtest \ · 11 unmodified lines
1212 test3 \
1313 speedtest \
1414 btest \
15+ test1b\
16+ test2b\
17+ test3b\
1518 weaktest
1619
1720 # test4 # this test does not seem to work on any platform
@@ -20,6 +23,9 @@ TESTS = libtest \ · 2 unmodified lines
2023 # bounds-checking is supported only on i386
2124 ifneq ($(ARCH),i386)
2225 TESTS := $(filter-out btest,$(TESTS))
26+ TESTS := $(filter-out test1b,$(TESTS))
27+ TESTS := $(filter-out test2b,$(TESTS))
28+ TESTS := $(filter-out test3b,$(TESTS))
2329 endif
2430
2531 # these should work too
@@ -87,18 +93,33 @@ test1: test.ref · 61 unmodified lines
8793 $(TCC) -run tcctest.c > test.out1
8894 @if diff -u test.ref test.out1 ; then echo "Auto Test OK"; fi
8995
96+test1b: test.ref
97+ @echo ------------ $@ ------------
98+ $(TCC) -b -run tcctest.c > test.out1b
99+ @if diff -u test.ref test.out1b ; then echo "Auto Test OK"; fi
100+
90101 # iterated test2 (compile tcc then compile tcctest.c !)
91102 test2: test.ref
92103 @echo ------------ $@ ------------
93104 $(TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out2
94105 @if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi
95106
107+test2b: test.ref ../bcheck.o
108+ @echo ------------ $@ ------------
109+ $(TCC) -b $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out2b
110+ @if diff -u test.ref test.out2b ; then echo "Auto Test2b OK"; fi
111+
96112 # iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
97113 test3: test.ref
98114 @echo ------------ $@ ------------
99115 $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out3
100116 @if diff -u test.ref test.out3 ; then echo "Auto Test3 OK"; fi
101117
118+test3b: test.ref
119+ @echo ------------ $@ ------------
120+ $(TCC) -b $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out3b
121+ @if diff -u test.ref test.out3b ; then echo "Auto Test3 OK"; fi
122+
102123 # binary output test
103124 test4: test.ref
104125 @echo ------------ $@ ------------
@@ -190,5 +211,5 @@ cache: tcc_g · 85 unmodified lines
190211
191212 # clean
192213 clean:
193− rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.gcc \
214+ rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.gcc \
194215 tcctest[1234] ex? libtcc_test$(EXESUF) tcc_g tcclib.h

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t