mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-02 06:20:10 +08:00
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
This commit is contained in:
commit
a55ecf6d2c
3
.gitignore
vendored
3
.gitignore
vendored
@ -11,8 +11,11 @@ tc1.c
|
|||||||
error.c
|
error.c
|
||||||
i386-gen1.c
|
i386-gen1.c
|
||||||
test.out1
|
test.out1
|
||||||
|
test.out1b
|
||||||
test.out2
|
test.out2
|
||||||
|
test.out2b
|
||||||
test.out3
|
test.out3
|
||||||
|
test.out3b
|
||||||
web.sh
|
web.sh
|
||||||
memdebug.c
|
memdebug.c
|
||||||
bench
|
bench
|
||||||
|
35
lib/bcheck.c
35
lib/bcheck.c
@ -25,6 +25,7 @@
|
|||||||
&& !defined(__DragonFly__) && !defined(__OpenBSD__)
|
&& !defined(__DragonFly__) && !defined(__OpenBSD__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
//#define BOUND_DEBUG
|
//#define BOUND_DEBUG
|
||||||
|
|
||||||
@ -94,9 +95,6 @@ static void *saved_realloc_hook;
|
|||||||
static void *saved_memalign_hook;
|
static void *saved_memalign_hook;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* linker definitions */
|
|
||||||
extern char _end;
|
|
||||||
|
|
||||||
/* TCC definitions */
|
/* TCC definitions */
|
||||||
extern char __bounds_start; /* start of static bounds table */
|
extern char __bounds_start; /* start of static bounds table */
|
||||||
/* error message, just for TCC */
|
/* error message, just for TCC */
|
||||||
@ -379,9 +377,32 @@ void __bound_init(void)
|
|||||||
|
|
||||||
#if !defined(__TINYC__) && defined(CONFIG_TCC_MALLOC_HOOKS)
|
#if !defined(__TINYC__) && defined(CONFIG_TCC_MALLOC_HOOKS)
|
||||||
/* malloc zone is also marked invalid. can only use that with
|
/* malloc zone is also marked invalid. can only use that with
|
||||||
hooks because all libs should use the same malloc. The solution
|
* hooks because all libs should use the same malloc. The solution
|
||||||
would be to build a new malloc for tcc. */
|
* would be to build a new malloc for tcc.
|
||||||
start = (unsigned long)&_end;
|
*
|
||||||
|
* 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;
|
size = 128 * 0x100000;
|
||||||
mark_invalid(start, size);
|
mark_invalid(start, size);
|
||||||
#endif
|
#endif
|
||||||
@ -592,7 +613,7 @@ int __bound_delete_region(void *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* last page */
|
/* last page */
|
||||||
page = get_page(t2_end);
|
page = get_page(t1_end);
|
||||||
e2 = (BoundEntry *)((char *)page + t2_end);
|
e2 = (BoundEntry *)((char *)page + t2_end);
|
||||||
for(e=page;e<e2;e++) {
|
for(e=page;e<e2;e++) {
|
||||||
e->start = 0;
|
e->start = 0;
|
||||||
|
3
tcc.h
3
tcc.h
@ -1127,7 +1127,8 @@ ST_DATA Sym *local_label_stack;
|
|||||||
ST_DATA Sym *global_label_stack;
|
ST_DATA Sym *global_label_stack;
|
||||||
ST_DATA Sym *define_stack;
|
ST_DATA Sym *define_stack;
|
||||||
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
|
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 rsym, anon_sym, ind, loc;
|
||||||
|
|
||||||
ST_DATA int const_wanted; /* true if constant wanted */
|
ST_DATA int const_wanted; /* true if constant wanted */
|
||||||
|
2
tccgen.c
2
tccgen.c
@ -55,7 +55,7 @@ ST_DATA Sym *define_stack;
|
|||||||
ST_DATA Sym *global_label_stack;
|
ST_DATA Sym *global_label_stack;
|
||||||
ST_DATA Sym *local_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 const_wanted; /* true if constant wanted */
|
||||||
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
|
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
|
||||||
|
1
tccpp.c
1
tccpp.c
@ -3041,7 +3041,6 @@ ST_FUNC void preprocess_init(TCCState *s1)
|
|||||||
s1->ifdef_stack_ptr = s1->ifdef_stack;
|
s1->ifdef_stack_ptr = s1->ifdef_stack;
|
||||||
file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
||||||
|
|
||||||
/* XXX: not ANSI compliant: bound checking says error */
|
|
||||||
vtop = vstack - 1;
|
vtop = vstack - 1;
|
||||||
s1->pack_stack[0] = 0;
|
s1->pack_stack[0] = 0;
|
||||||
s1->pack_stack_ptr = s1->pack_stack;
|
s1->pack_stack_ptr = s1->pack_stack;
|
||||||
|
@ -12,6 +12,9 @@ TESTS = libtest \
|
|||||||
test3 \
|
test3 \
|
||||||
speedtest \
|
speedtest \
|
||||||
btest \
|
btest \
|
||||||
|
test1b\
|
||||||
|
test2b\
|
||||||
|
test3b\
|
||||||
weaktest
|
weaktest
|
||||||
|
|
||||||
# test4 # this test does not seem to work on any platform
|
# test4 # this test does not seem to work on any platform
|
||||||
@ -20,6 +23,9 @@ TESTS = libtest \
|
|||||||
# bounds-checking is supported only on i386
|
# bounds-checking is supported only on i386
|
||||||
ifneq ($(ARCH),i386)
|
ifneq ($(ARCH),i386)
|
||||||
TESTS := $(filter-out btest,$(TESTS))
|
TESTS := $(filter-out btest,$(TESTS))
|
||||||
|
TESTS := $(filter-out test1b,$(TESTS))
|
||||||
|
TESTS := $(filter-out test2b,$(TESTS))
|
||||||
|
TESTS := $(filter-out test3b,$(TESTS))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# these should work too
|
# these should work too
|
||||||
@ -87,18 +93,33 @@ test1: test.ref
|
|||||||
$(TCC) -run tcctest.c > test.out1
|
$(TCC) -run tcctest.c > test.out1
|
||||||
@if diff -u test.ref test.out1 ; then echo "Auto Test OK"; fi
|
@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 !)
|
# iterated test2 (compile tcc then compile tcctest.c !)
|
||||||
test2: test.ref
|
test2: test.ref
|
||||||
@echo ------------ $@ ------------
|
@echo ------------ $@ ------------
|
||||||
$(TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out2
|
$(TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out2
|
||||||
@if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi
|
@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 !)
|
# iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
|
||||||
test3: test.ref
|
test3: test.ref
|
||||||
@echo ------------ $@ ------------
|
@echo ------------ $@ ------------
|
||||||
$(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out3
|
$(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
|
@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
|
# binary output test
|
||||||
test4: test.ref
|
test4: test.ref
|
||||||
@echo ------------ $@ ------------
|
@echo ------------ $@ ------------
|
||||||
@ -190,5 +211,5 @@ cache: tcc_g
|
|||||||
|
|
||||||
# clean
|
# clean
|
||||||
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
|
tcctest[1234] ex? libtcc_test$(EXESUF) tcc_g tcclib.h
|
||||||
|
Loading…
Reference in New Issue
Block a user