added optionnal bound check compile - fixed error reporting

This commit is contained in:
bellard 2002-03-03 22:45:55 +00:00
parent 6933ac641f
commit 4226681d36
4 changed files with 75 additions and 36 deletions

View File

@ -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 },

View File

@ -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 */
/*************************************************************/

View File

@ -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 */
/*************************************************************/

53
tcc.c
View File

@ -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);
}
}