* define targetos=Windows when --enable-tcc32-mingw, --enable-cygwin, ... * use TARGETOS insteed HOST_OS when selecting PROGS * use "$(tccdir)" insteed $(tccdir) on install (spaces in path) * install tcc.exe too * produce bcheck.o when cross-compiling too (lib/Makefile) * force bcheck.o linking by compiling inside tcc_set_output_type() a dummy program with local array. Otherwise bcheck.o may be not linked. * replace %xz format specifier with %p in bcheck (don't supported on Windows) * call a __bound_init when __bound_ptr_add, __bound_ptr_indir, __bound_new_region, __bound_delete_region called. This is because a __bound_init inside ".init" section is not called on Windows for unknown reason. * print on stderr a message when an illegal pointer is returned: there is no segmentation violation on Windows for a program compiled with "tcc -b" * remove "C:" subdir on clean if $HOST_OS = "Linux" * default CFLAGS="-Wall -g -O0" insteed CFLAGS="-Wall -g -O2" to speed up compilation and more precise debugging.
Unified · Split
| @@ -89,7 +89,7 @@ $(ARM_FPA_LD_CROSS)_LINK = arm-fpa-ld-tcc$(EXESUF) · 88 unmodified lines | ||
| 89 | 89 | $(ARM_VFP_CROSS)_LINK = arm-vfp-tcc$(EXESUF) |
| 90 | 90 | $(ARM_EABI_CROSS)_LINK = arm-eabi-tcc$(EXESUF) |
| 91 | 91 | |
| 92 | −ifeq ($(HOST_OS),Windows) | |
| 92 | +ifeq ($(TARGETOS),Windows) | |
| 93 | 93 | ifeq ($(ARCH),i386) |
| 94 | 94 | PROGS:=$($(WIN32_CROSS)_LINK) |
| 95 | 95 | $($(WIN32_CROSS)_LINK)_TCC = yes |
| @@ -100,7 +100,7 @@ $($(WIN64_CROSS)_LINK)_TCC = yes · 4 unmodified lines | ||
| 100 | 100 | endif |
| 101 | 101 | endif |
| 102 | 102 | |
| 103 | −ifeq ($(HOST_OS),Linux) | |
| 103 | +ifeq ($(TARGETOS),Linux) | |
| 104 | 104 | ifeq ($(ARCH),i386) |
| 105 | 105 | PROGS:=$($(I386_CROSS)_LINK) |
| 106 | 106 | $($(I386_CROSS)_LINK)_TCC = yes |
| @@ -140,7 +140,6 @@ PROGS_CROSS=$($(X64_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $ · 33 unmodified lines | ||
| 140 | 140 | LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \ |
| 141 | 141 | lib/arm64/libtcc1.a |
| 142 | 142 | LIBTCC1=libtcc1.a |
| 143 | −BCHECK=yes | |
| 144 | 143 | else ifeq ($(ARCH),x86-64) |
| 145 | 144 | ifeq ($(TARGETOS),Darwin) |
| 146 | 145 | NATIVE_FILES=$(X86_64_FILES) |
| @@ -291,10 +290,6 @@ install: $(PROGS) $(TCCLIBS) $(TCCDOCS) · 144 unmodified lines | ||
| 291 | 290 | ifneq ($(LIBTCC1),) |
| 292 | 291 | mkdir -p "$(tccdir)/$(ARCH)" |
| 293 | 292 | $(INSTALL) -m644 $(LIBTCC1) "$(tccdir)/$(ARCH)" |
| 294 | −endif | |
| 295 | −ifneq ($(BCHECK),) | |
| 296 | − -mkdir -p "$(tccdir)/$(ARCH)" | |
| 297 | − $(INSTALL) -m644 lib/$(ARCH)/bcheck.o "$(tccdir)/$(ARCH)" | |
| 298 | 293 | endif |
| 299 | 294 | $(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include" |
| 300 | 295 | mkdir -p "$(libdir)" |
| @@ -315,7 +310,6 @@ ifdef CONFIG_CROSS · 14 unmodified lines | ||
| 315 | 310 | ifneq ($(HOST_OS),Darwin) |
| 316 | 311 | mkdir -p "$(tccdir)/arm64" |
| 317 | 312 | $(INSTALL) -m644 lib/arm64/libtcc1.a "$(tccdir)/arm64" |
| 318 | − $(INSTALL) -m644 lib/i386/bcheck.o "$(tccdir)/i386" | |
| 319 | 313 | endif |
| 320 | 314 | $(INSTALL) -m644 lib/i386/libtcc1.a "$(tccdir)/i386" |
| 321 | 315 | $(INSTALL) -m644 lib/x86_64/libtcc1.a "$(tccdir)/x86-64" |
| @@ -346,13 +340,14 @@ install: $(PROGS) $(TCCLIBS) $(TCCDOCS) · 24 unmodified lines | ||
| 346 | 340 | mkdir -p "$(tccdir)/doc" |
| 347 | 341 | mkdir -p "$(tccdir)/libtcc" |
| 348 | 342 | $(INSTALLBIN) -m755 $(PROGS) "$(tccdir)" |
| 343 | + $(INSTALLBIN) -m755 tcc.exe "$(tccdir)" | |
| 349 | 344 | $(INSTALL) -m644 $(LIBTCC1) $(top_srcdir)/win32/lib/*.def "$(tccdir)/lib" |
| 350 | 345 | cp -r $(top_srcdir)/win32/include/. "$(tccdir)/include" |
| 351 | 346 | cp -r $(top_srcdir)/win32/examples/. "$(tccdir)/examples" |
| 352 | 347 | $(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include" |
| 353 | 348 | $(INSTALL) -m644 tcc-doc.html $(top_srcdir)/win32/tcc-win32.txt "$(tccdir)/doc" |
| 354 | 349 | $(INSTALL) -m644 $(top_srcdir)/libtcc.h $(LIBTCC_EXTRA) "$(tccdir)/libtcc" |
| 355 | − $(INSTALL) -m644 $(LIBTCC) $(tccdir) | |
| 350 | + $(INSTALL) -m644 $(LIBTCC) "$(tccdir)" | |
| 356 | 351 | ifdef CONFIG_CROSS |
| 357 | 352 | mkdir -p "$(tccdir)/lib/32" |
| 358 | 353 | mkdir -p "$(tccdir)/lib/64" |
| @@ -385,6 +380,9 @@ clean: · 26 unmodified lines | ||
| 385 | 380 | rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.log \ |
| 386 | 381 | *.exe a.out tags TAGS libtcc_test$(EXESUF) tcc$(EXESUF) |
| 387 | 382 | -rm -r $(ARCH) arm64 |
| 383 | +ifeq ($(HOST_OS),Linux) | |
| 384 | + -rm -r ./C: | |
| 385 | +endif | |
| 388 | 386 | -rm *-tcc$(EXESUF) |
| 389 | 387 | $(MAKE) -C tests $@ |
| 390 | 388 | ifneq ($(LIBTCC1),) |
| @@ -47,7 +47,12 @@ tcc_elfinterp="" · 46 unmodified lines | ||
| 47 | 47 | tcc_lddir= |
| 48 | 48 | confvars= |
| 49 | 49 | cpu= |
| 50 | + | |
| 50 | 51 | host_os=`uname` |
| 52 | +case $host_os in | |
| 53 | + MINGW32*) host_os=Windows; ;; | |
| 54 | + *) ;; | |
| 55 | +esac | |
| 51 | 56 | |
| 52 | 57 | # OS specific |
| 53 | 58 | targetos=`uname` |
| @@ -170,13 +175,13 @@ for opt do · 116 unmodified lines | ||
| 170 | 175 | ;; |
| 171 | 176 | --enable-gprof) gprof="yes" |
| 172 | 177 | ;; |
| 173 | − --enable-mingw32) mingw32="yes" ; cross_prefix="i686-pc-mingw32-" ; cpu=x86 | |
| 178 | + --enable-mingw32) mingw32="yes" ; cross_prefix="i686-pc-mingw32-" ; cpu=x86; targetos=Windows; | |
| 174 | 179 | ;; |
| 175 | − --enable-cygwin) mingw32="yes" ; cygwin="yes" ; cross_prefix="mingw32-" ; cpu=x86 | |
| 180 | + --enable-cygwin) mingw32="yes" ; cygwin="yes" ; cross_prefix="mingw32-" ; cpu=x86; targetos=Windows; | |
| 176 | 181 | ;; |
| 177 | − --enable-tcc32-mingw) mingw32="yes" ; cross_prefix="i386-win-" ; cpu=x86; cc=tcc | |
| 182 | + --enable-tcc32-mingw) mingw32="yes" ; cross_prefix="i386-win-" ; cpu=x86; cc=tcc; targetos=Windows; | |
| 178 | 183 | ;; |
| 179 | − --enable-tcc64-mingw) mingw32="yes" ; cross_prefix="x86_64-win-" ; cpu=x86_64; cc=tcc | |
| 184 | + --enable-tcc64-mingw) mingw32="yes" ; cross_prefix="x86_64-win-" ; cpu=x86_64; cc=tcc; targetos=Windows; | |
| 180 | 185 | ;; |
| 181 | 186 | --enable-cross) build_cross="yes" |
| 182 | 187 | ;; |
| @@ -210,7 +215,7 @@ classify_cpu "$cpu" · 27 unmodified lines | ||
| 210 | 215 | |
| 211 | 216 | # Checking for CFLAGS |
| 212 | 217 | if test -z "$CFLAGS"; then |
| 213 | − CFLAGS="-Wall -g -O2" | |
| 218 | + CFLAGS="-Wall -g -O0" | |
| 214 | 219 | fi |
| 215 | 220 | |
| 216 | 221 | if test "$mingw32" = "yes" ; then |
| @@ -32,9 +32,9 @@ ifndef TARGET # native library · 31 unmodified lines | ||
| 32 | 32 | endif |
| 33 | 33 | endif |
| 34 | 34 | endif |
| 35 | − BCHECK_O = bcheck.o | |
| 36 | 35 | endif |
| 37 | 36 | |
| 37 | +BCHECK_O = bcheck.o | |
| 38 | 38 | DIR = $(TARGET) |
| 39 | 39 | |
| 40 | 40 | native : ../libtcc1.a |
| @@ -150,6 +150,7 @@ static BoundEntry *__bound_find_region(BoundEntry *e1, void *p) · 149 unmodified lines | ||
| 150 | 150 | static void bound_error(const char *fmt, ...) |
| 151 | 151 | { |
| 152 | 152 | __bound_error_msg = fmt; |
| 153 | + fprintf(stderr,"%s %s: %s\n", __FILE__, __FUNCTION__, fmt); | |
| 153 | 154 | *(int *)0 = 0; /* force a runtime error */ |
| 154 | 155 | } |
| 155 | 156 | |
| @@ -164,6 +165,9 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 8 unmodified lines | ||
| 164 | 165 | { |
| 165 | 166 | size_t addr = (size_t)p; |
| 166 | 167 | BoundEntry *e; |
| 168 | + | |
| 169 | + __bound_init(); | |
| 170 | + | |
| 167 | 171 | #if defined(BOUND_DEBUG) |
| 168 | 172 | printf("%s %s: 0x%x %d\n", __FILE__, __FUNCTION__, (int)p, offset); |
| 169 | 173 | #endif |
| @@ -179,9 +183,7 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 9 unmodified lines | ||
| 179 | 183 | } |
| 180 | 184 | addr += offset; |
| 181 | 185 | if (addr >= e->size) { |
| 182 | − #if defined(BOUND_DEBUG) | |
| 183 | − printf("%s %s: 0x%zx is outside of the region\n", __FILE__, __FUNCTION__, p + offset); | |
| 184 | − #endif | |
| 186 | + fprintf(stderr,"%s %s: %p is outside of the region\n", __FILE__, __FUNCTION__, p + offset); | |
| 185 | 187 | return INVALID_POINTER; /* return an invalid pointer */ |
| 186 | 188 | } |
| 187 | 189 | return p + offset; |
| @@ -195,6 +197,7 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ · 7 unmodified lines | ||
| 195 | 197 | size_t addr = (size_t)p; \ |
| 196 | 198 | BoundEntry *e; \ |
| 197 | 199 | \ |
| 200 | + __bound_init(); \ | |
| 198 | 201 | e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \ |
| 199 | 202 | e = (BoundEntry *)((char *)e + \ |
| 200 | 203 | ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & \ |
| @@ -205,8 +208,10 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ · 4 unmodified lines | ||
| 205 | 208 | addr = (size_t)p - e->start; \ |
| 206 | 209 | } \ |
| 207 | 210 | addr += offset + dsize; \ |
| 208 | − if (addr > e->size) \ | |
| 211 | + if (addr > e->size) { \ | |
| 212 | + fprintf(stderr,"%s %s: %p is outside of the region\n", __FILE__, __FUNCTION__, p + offset); \ | |
| 209 | 213 | return INVALID_POINTER; /* return an invalid pointer */ \ |
| 214 | + } \ | |
| 210 | 215 | return p + offset; \ |
| 211 | 216 | } |
| 212 | 217 | |
| @@ -228,7 +233,7 @@ void FASTCALL __bound_local_new(void *p1) · 15 unmodified lines | ||
| 228 | 233 | { |
| 229 | 234 | size_t addr, size, fp, *p = p1; |
| 230 | 235 | #ifdef BOUND_DEBUG |
| 231 | − fprintf(stderr, "%s, %s start p1=%zx *p1=%zx\n", __FILE__, __FUNCTION__, p, *p); | |
| 236 | + fprintf(stderr, "%s, %s start p1=%p *p1=%p\n", __FILE__, __FUNCTION__, p, *p); | |
| 232 | 237 | #endif |
| 233 | 238 | GET_CALLER_FP(fp); |
| 234 | 239 | for(;;) { |
| @@ -364,6 +369,12 @@ void __bound_init(void) · 129 unmodified lines | ||
| 364 | 369 | size_t start, size; |
| 365 | 370 | size_t *p; |
| 366 | 371 | |
| 372 | + static int inited; | |
| 373 | + if (inited) | |
| 374 | + return; | |
| 375 | + | |
| 376 | + inited = 1; | |
| 377 | + | |
| 367 | 378 | #ifdef BOUND_DEBUG |
| 368 | 379 | fprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__); |
| 369 | 380 | #endif |
| @@ -444,7 +455,7 @@ void __bound_main_arg(void **p) · 74 unmodified lines | ||
| 444 | 455 | void *start = p; |
| 445 | 456 | while (*p++); |
| 446 | 457 | #ifdef BOUND_DEBUG |
| 447 | − fprintf(stderr, "%s, %s calling __bound_new_region(%p, %llx)\n", | |
| 458 | + fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", | |
| 448 | 459 | __FILE__, __FUNCTION__, (void *) p - start); |
| 449 | 460 | #endif |
| 450 | 461 | __bound_new_region(start, (void *) p - start); |
| @@ -482,8 +493,10 @@ void __bound_new_region(void *p, size_t size) · 31 unmodified lines | ||
| 482 | 493 | BoundEntry *page, *e, *e2; |
| 483 | 494 | size_t t1_start, t1_end, i, t2_start, t2_end; |
| 484 | 495 | |
| 496 | + __bound_init(); | |
| 497 | + | |
| 485 | 498 | #ifdef BOUND_DEBUG |
| 486 | − fprintf(stderr, "%s, %s(%p, %zx) start\n", | |
| 499 | + fprintf(stderr, "%s, %s(%p, %p) start\n", | |
| 487 | 500 | __FILE__, __FUNCTION__, p, size); |
| 488 | 501 | #endif |
| 489 | 502 | |
| @@ -595,6 +608,8 @@ int __bound_delete_region(void *p) · 105 unmodified lines | ||
| 595 | 608 | BoundEntry *page, *e, *e2; |
| 596 | 609 | size_t t1_start, t1_end, t2_start, t2_end, i; |
| 597 | 610 | |
| 611 | + __bound_init(); | |
| 612 | + | |
| 598 | 613 | #ifdef BOUND_DEBUG |
| 599 | 614 | fprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__); |
| 600 | 615 | #endif |
| @@ -757,7 +772,7 @@ void *__bound_malloc(size_t size, const void *caller) · 156 unmodified lines | ||
| 757 | 772 | return NULL; |
| 758 | 773 | |
| 759 | 774 | #ifdef BOUND_DEBUG |
| 760 | − fprintf(stderr, "%s, %s calling __bound_new_region(%p, %llx)\n", | |
| 775 | + fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", | |
| 761 | 776 | __FILE__, __FUNCTION__, ptr, size); |
| 762 | 777 | #endif |
| 763 | 778 | __bound_new_region(ptr, size); |
| @@ -791,7 +806,7 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) · 27 unmodified lines | ||
| 791 | 806 | return NULL; |
| 792 | 807 | |
| 793 | 808 | #ifdef BOUND_DEBUG |
| 794 | − fprintf(stderr, "%s, %s calling __bound_new_region(%p, %llx)\n", | |
| 809 | + fprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", | |
| 795 | 810 | __FILE__, __FUNCTION__, ptr, size); |
| 796 | 811 | #endif |
| 797 | 812 | __bound_new_region(ptr, size); |
| @@ -1390,6 +1390,17 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 1389 unmodified lines | ||
| 1390 | 1390 | tcc_add_crt(s, "crti.o"); |
| 1391 | 1391 | } |
| 1392 | 1392 | #endif |
| 1393 | + | |
| 1394 | +#ifdef CONFIG_TCC_BCHECK | |
| 1395 | + if (s->do_bounds_check && (output_type == TCC_OUTPUT_EXE)) | |
| 1396 | + { | |
| 1397 | + /* XXX force a bcheck.o linking by compiling a function with a local array. | |
| 1398 | + Otherwise bcheck.o may be not linked. */ | |
| 1399 | + | |
| 1400 | + if (tcc_compile_string(s, "static void __bound_check_dummy_func(){int v[1];}") == -1) | |
| 1401 | + tcc_warning("compiling __bound_check_dummy_func failed"); | |
| 1402 | + } | |
| 1403 | +#endif | |
| 1393 | 1404 | return 0; |
| 1394 | 1405 | } |
| 1395 | 1406 | |
| @@ -1569,9 +1569,6 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1) · 1568 unmodified lines | ||
| 1569 | 1569 | { |
| 1570 | 1570 | #ifdef CONFIG_TCC_BCHECK |
| 1571 | 1571 | addr_t *ptr; |
| 1572 | − Section *init_section; | |
| 1573 | − unsigned char *pinit; | |
| 1574 | − int sym_index; | |
| 1575 | 1572 | |
| 1576 | 1573 | if (0 == s1->do_bounds_check) |
| 1577 | 1574 | return; |
| @@ -1585,19 +1582,23 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1) · 7 unmodified lines | ||
| 1585 | 1582 | #ifdef TCC_TARGET_I386 |
| 1586 | 1583 | if (s1->output_type != TCC_OUTPUT_MEMORY) { |
| 1587 | 1584 | /* add 'call __bound_init()' in .init section */ |
| 1588 | − init_section = find_section(s1, ".init"); | |
| 1589 | − pinit = section_ptr_add(init_section, 5); | |
| 1590 | − pinit[0] = 0xe8; | |
| 1591 | − put32(pinit + 1, -4); | |
| 1592 | − sym_index = find_elf_sym(symtab_section, "__bound_init"); | |
| 1593 | − if (!sym_index) { | |
| 1594 | − tcc_add_support(s1, "bcheck.o"); | |
| 1595 | − sym_index = find_elf_sym(symtab_section, "__bound_init"); | |
| 1596 | − if (!sym_index) | |
| 1597 | − tcc_error("__bound_init not defined"); | |
| 1598 | − } | |
| 1599 | − put_elf_reloc(symtab_section, init_section, | |
| 1585 | + | |
| 1586 | + /* XXX not called on MSYS, reason is unknown. For this | |
| 1587 | + case a call to __bound_init is performed in bcheck.c | |
| 1588 | + when __bound_ptr_add, __bound_new_region, | |
| 1589 | + __bound_delete_region called */ | |
| 1590 | + | |
| 1591 | + int sym_index = find_elf_sym(symtab_section, "__bound_init"); | |
| 1592 | + if (sym_index) { | |
| 1593 | + Section *init_section = find_section(s1, ".init"); | |
| 1594 | + unsigned char *pinit = section_ptr_add(init_section, 5); | |
| 1595 | + pinit[0] = 0xe8; | |
| 1596 | + put32(pinit + 1, -4); | |
| 1597 | + put_elf_reloc(symtab_section, init_section, | |
| 1600 | 1598 | init_section->data_offset - 4, R_386_PC32, sym_index); |
| 1599 | + } | |
| 1600 | + else | |
| 1601 | + tcc_warning("__bound_init not defined"); | |
| 1601 | 1602 | } |
| 1602 | 1603 | #endif |
| 1603 | 1604 | #endif |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | #include <stdlib.h> |
| 2 | 2 | #include <stdio.h> |
| 3 | +#include <string.h> | |
| 3 | 4 | |
| 4 | 5 | #define NB_ITS 1000000 |
| 5 | 6 | //#define NB_ITS 1 |