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