added optionnal bound check compile - fixed error reporting
This commit is contained in:
53
tcc.c
53
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user