diff --git a/bcheck.c b/bcheck.c index 932035f..242c055 100644 --- a/bcheck.c +++ b/bcheck.c @@ -24,6 +24,9 @@ bound checking not used) */ //#define BOUND_STATIC +/* use malloc hooks. Currently the code cannot be reliable if no hooks */ +#define CONFIG_TCC_MALLOC_HOOKS + #define BOUND_T1_BITS 13 #define BOUND_T2_BITS 11 #define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS) @@ -80,7 +83,7 @@ static void libc_free(void *ptr); static void install_malloc_hooks(void); static void restore_malloc_hooks(void); -#ifndef WIN32 +#ifdef CONFIG_TCC_MALLOC_HOOKS static void *saved_malloc_hook; static void *saved_free_hook; static void *saved_realloc_hook; @@ -407,8 +410,10 @@ void __bound_init(void) size = BOUND_T23_SIZE; mark_invalid(start, size); -#if !defined(__TINYC__) && !defined(WIN32) - /* malloc zone is also marked invalid */ +#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; size = 128 * 0x100000; mark_invalid(start, size); @@ -642,7 +647,7 @@ static unsigned long get_region_size(void *p) static void install_malloc_hooks(void) { -#ifndef WIN32 +#ifdef CONFIG_TCC_MALLOC_HOOKS saved_malloc_hook = __malloc_hook; saved_free_hook = __free_hook; saved_realloc_hook = __realloc_hook; @@ -656,7 +661,7 @@ static void install_malloc_hooks(void) static void restore_malloc_hooks(void) { -#ifndef WIN32 +#ifdef CONFIG_TCC_MALLOC_HOOKS __malloc_hook = saved_malloc_hook; __free_hook = saved_free_hook; __realloc_hook = saved_realloc_hook; @@ -698,7 +703,6 @@ void *__bound_malloc(size_t size, const void *caller) return ptr; } -#ifndef WIN32 void *__bound_memalign(size_t size, size_t align, const void *caller) { void *ptr; @@ -717,7 +721,6 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) __bound_new_region(ptr, size); return ptr; } -#endif void __bound_free(void *ptr, const void *caller) { @@ -750,6 +753,19 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller) } } +#ifndef CONFIG_TCC_MALLOC_HOOKS +void *__bound_calloc(size_t nmemb, size_t size) +{ + void *ptr; + size = size * nmemb; + ptr = __bound_malloc(size); + if (!ptr) + return NULL; + memset(ptr, 0, size); + return ptr; +} +#endif + #if 0 static void bound_dump(void) { @@ -844,6 +860,13 @@ typedef struct BCSyms { } BCSyms; static BCSyms bcheck_syms[] = { +#ifndef CONFIG_TCC_MALLOC_HOOKS + { "malloc", __bound_malloc }, + { "free", __bound_free }, + { "realloc", __bound_realloc }, + { "memalign", __bound_memalign }, + { "calloc", __bound_calloc }, +#endif { "memcpy", __bound_memcpy }, { "memmove", __bound_memmove }, { "memset", __bound_memset }, diff --git a/i386-gen.c b/i386-gen.c index 9aad2e1..43fb083 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -412,6 +412,7 @@ void gfunc_prolog(int t) /* generate function epilog */ void gfunc_epilog(void) { +#ifdef CONFIG_TCC_BCHECK if (do_bounds_check && func_bound_ptr != lbounds_section->data_ptr) { int saved_ind; int *bounds_ptr; @@ -431,6 +432,7 @@ void gfunc_epilog(void) oad(0xe8, (int)__bound_local_delete - ind - 5); o(0x585a); /* restore returned value, if any */ } +#endif o(0xc9); /* leave */ if (func_ret_sub == 0) { o(0xc3); /* ret */ @@ -818,7 +820,7 @@ void gen_cvt_ftof(int t) } /* bound check support functions */ - +#ifdef CONFIG_TCC_BCHECK /* generate first part of bounded pointer addition */ void gen_bounded_ptr_add1(void) { @@ -859,6 +861,7 @@ void gen_bounded_ptr_add2(int deref) /* return pointer is there */ vtop->r = REG_EAX; } +#endif /* end of X86 code generator */ /*************************************************************/ diff --git a/il-gen.c b/il-gen.c index 3253c5c..5e3a24b 100644 --- a/il-gen.c +++ b/il-gen.c @@ -662,20 +662,6 @@ void gen_cvt_ftof(int t) } } -/* bound check support functions */ - -/* generate first part of bounded pointer addition */ -void gen_bounded_ptr_add1(void) -{ - /* not handled */ -} - -/* if deref is true, then also test dereferencing */ -void gen_bounded_ptr_add2(int deref) -{ - /* not handled */ -} - -/* end of X86 code generator */ +/* end of CIL code generator */ /*************************************************************/ diff --git a/tcc.c b/tcc.c index f2c9d07..efbb125 100644 --- a/tcc.c +++ b/tcc.c @@ -51,6 +51,10 @@ #define TCC_TARGET_I386 #endif +#if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL) +#define CONFIG_TCC_BCHECK /* enable bound checking code */ +#endif + /* amount of virtual memory associated to a section (currently, we do not realloc them) */ #define SECTION_VSIZE (1024 * 1024) @@ -454,6 +458,9 @@ char *tcc_keywords = #ifdef WIN32 #define snprintf _snprintf +#endif + +#if defined(WIN32) || defined(TCC_UCLIBC) /* currently incorrect */ long double strtold(const char *nptr, char **endptr) { @@ -534,7 +541,9 @@ static inline int is_float(int t) return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT; } +#ifdef CONFIG_TCC_BCHECK #include "bcheck.c" +#endif #ifdef TCC_TARGET_I386 #include "i386-gen.c" @@ -797,10 +806,14 @@ static inline int toup(int c) void printline(void) { BufferedFile **f; - for(f = include_stack; f < include_stack_ptr; f++) - fprintf(stderr, "In file included from %s:%d:\n", - (*f)->filename, (*f)->line_num); - fprintf(stderr, "%s:%d: ", file->filename, file->line_num); + if (file) { + for(f = include_stack; f < include_stack_ptr; f++) + fprintf(stderr, "In file included from %s:%d:\n", + (*f)->filename, (*f)->line_num); + fprintf(stderr, "%s:%d: ", file->filename, file->line_num); + } else { + fprintf(stderr, "tcc: "); + } } void error(const char *fmt, ...) @@ -2516,6 +2529,7 @@ void gaddrof(void) vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL; } +#ifdef CONFIG_TCC_BCHECK /* generate lvalue bound code */ void gbound(void) { @@ -2529,6 +2543,7 @@ void gbound(void) vtop->r |= VT_LVAL; } } +#endif /* store vtop a register belonging to class 'rc'. lvalues are converted to values. Cannot be used if cannot be converted to @@ -2568,8 +2583,10 @@ int gv(int rc) data_offset += size << 2; data_section->data_ptr = (unsigned char *)data_offset; } +#ifdef CONFIG_TCC_BCHECK if (vtop->r & VT_MUSTBOUND) gbound(); +#endif r = vtop->r & VT_VALMASK; /* need to reload if: @@ -3127,6 +3144,7 @@ void gen_op(int op) /* XXX: cast to int ? (long long case) */ vpushi(pointed_size(vtop[-1].t)); gen_op('*'); +#ifdef CONFIG_TCC_BCHECK /* if evaluating constant expression, no code should be generated, so no bound check */ if (do_bounds_check && !const_wanted) { @@ -3139,7 +3157,9 @@ void gen_op(int op) } gen_bounded_ptr_add1(); gen_bounded_ptr_add2(0); - } else { + } else +#endif + { gen_opc(op); } /* put again type if gen_opc() swaped operands */ @@ -3747,12 +3767,14 @@ void vstore(void) /* store result */ vstore(); } else { +#ifdef CONFIG_TCC_BCHECK /* bound check case */ if (vtop[-1].r & VT_MUSTBOUND) { vswap(); gbound(); vswap(); } +#endif rc = RC_INT; if (is_float(ft)) rc = RC_FLOAT; @@ -5854,12 +5876,14 @@ void open_dll(char *libname) static void *resolve_sym(const char *sym) { - void *ptr; +#ifdef CONFIG_TCC_BCHECK if (do_bounds_check) { + void *ptr; ptr = bound_resolve_sym(sym); if (ptr) return ptr; } +#endif return dlsym(NULL, sym); } @@ -6269,10 +6293,8 @@ int launch_exe(int argc, char **argv) #endif } +#ifdef CONFIG_TCC_BCHECK if (do_bounds_check) { -#ifdef WIN32 - error("bound checking currently not available for Windows"); -#else int *p, *p_end; __bound_init(); /* add all known static regions */ @@ -6282,8 +6304,8 @@ int launch_exe(int argc, char **argv) __bound_new_region((void *)p[0], p[1]); p += 2; } -#endif } +#endif t = (int (*)())s->c; return (*t)(argc, argv); @@ -6292,7 +6314,7 @@ int launch_exe(int argc, char **argv) void help(void) { - printf("tcc version 0.9.4 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" + printf("tcc version 0.9.5 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n" " [-i infile] infile [infile_args...]\n" "\n" @@ -6301,7 +6323,9 @@ void help(void) "-Usym : undefine 'sym'\n" "-llib : link with dynamic library 'lib'\n" "-g : generate runtime debug info\n" +#ifdef CONFIG_TCC_BCHECK "-b : compile with built-in memory and bounds checker (implies -g)\n" +#endif "-i infile : compile infile\n" ); } @@ -6368,6 +6392,7 @@ int main(int argc, char **argv) tcc_compile_file(argv[optind++]); } else if (!strcmp(r + 1, "bench")) { do_bench = 1; +#ifdef CONFIG_TCC_BCHECK } else if (r[1] == 'b') { if (!do_bounds_check) { do_bounds_check = 1; @@ -6381,8 +6406,11 @@ int main(int argc, char **argv) /* debug is implied */ goto debug_opt; } +#endif } else if (r[1] == 'g') { +#ifdef CONFIG_TCC_BCHECK debug_opt: +#endif if (!do_debug) { do_debug = 1; @@ -6409,8 +6437,7 @@ int main(int argc, char **argv) goto show_help; outfile = argv[optind++]; } else { - fprintf(stderr, "invalid option -- '%s'\n", r); - exit(1); + error("invalid option -- '%s'", r); } }