mirror of
https://github.com/frida/tinycc
synced 2024-11-28 02:29:38 +03: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) */
|
||||
//#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 },
|
||||
|
@ -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 */
|
||||
/*************************************************************/
|
||||
|
16
il-gen.c
16
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 */
|
||||
/*************************************************************/
|
||||
|
||||
|
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user