diff --git a/i386-gen.c b/i386-gen.c index 8016af9..2e29a6c 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -588,7 +588,9 @@ ST_FUNC void gfunc_epilog(void) addr_t v, saved_ind; #ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) + if (tcc_state->do_bounds_check && + (func_bound_offset != lbounds_section->data_offset || + tcc_state->alloca_vla_used)) gen_bounds_epilog(); #endif diff --git a/lib/bcheck.c b/lib/bcheck.c index 14cec50..d760801 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -460,15 +460,9 @@ void FASTCALL __bound_local_new(void *p1) if (print_calls) { p = p1; while ((addr = p[0])) { - if (addr == 1) { - dprintf(stderr, "%s, %s(): alloca/vla used\n", - __FILE__, __FUNCTION__); - } - else { - dprintf(stderr, "%s, %s(): %p 0x%lx\n", - __FILE__, __FUNCTION__, - (void *) (addr + fp), (unsigned long) p[1]); - } + dprintf(stderr, "%s, %s(): %p 0x%lx\n", + __FILE__, __FUNCTION__, + (void *) (addr + fp), (unsigned long) p[1]); p += 2; } } @@ -903,7 +897,7 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) { use_sem = 1; - dprintf (stderr, "%s, %s()n", __FILE__, __FUNCTION__); + dprintf (stderr, "%s, %s()\n", __FILE__, __FUNCTION__); return pthread_create_redir(thread, attr, start_routine, arg); } #endif diff --git a/tcc.h b/tcc.h index 6ff661e..e5e38b2 100644 --- a/tcc.h +++ b/tcc.h @@ -836,6 +836,7 @@ struct TCCState { /* bound check related sections */ Section *bounds_section; /* contains global data bound description */ Section *lbounds_section; /* contains local data bound description */ + int alloca_vla_used; #endif /* symbol sections */ Section *symtab_section; diff --git a/tccgen.c b/tccgen.c index aeceee2..ca8b8b3 100644 --- a/tccgen.c +++ b/tccgen.c @@ -5913,6 +5913,11 @@ special_math_val: Sym *sa; int nb_args, ret_nregs, ret_align, regsize, variadic; +#ifdef CONFIG_TCC_BCHECK + tcc_state->alloca_vla_used |= tcc_state->do_bounds_check && + (vtop->r & VT_SYM) && + vtop->sym->v == TOK_alloca; +#endif /* function call */ if ((vtop->type.t & VT_BTYPE) != VT_FUNC) { /* pointer test (no array accepted) */ @@ -7907,6 +7912,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, gen_vla_sp_save(addr); cur_scope->vla.loc = addr; cur_scope->vla.num++; +#ifdef CONFIG_TCC_BCHECK + tcc_state->alloca_vla_used |= bcheck; +#endif } else if (has_init) { size_t oldreloc_offset = 0; if (sec && sec->reloc) @@ -7939,6 +7947,9 @@ static void gen_function(Sym *sym) cur_scope = root_scope = &f; nocode_wanted = 0; +#ifdef CONFIG_TCC_BCHECK + tcc_state->alloca_vla_used = 0; +#endif ind = cur_text_section->data_offset; if (sym->a.aligned) { size_t newoff = section_add(cur_text_section, 0, diff --git a/tests/tests2/114_bound_signal.c b/tests/tests2/114_bound_signal.c new file mode 100644 index 0000000..55bc402 --- /dev/null +++ b/tests/tests2/114_bound_signal.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile int run = 1; +static int dummy[10]; +static sem_t sem; + +static void +add (void) +{ + int i; + + for (i = 0; i < (sizeof(dummy)/sizeof(dummy[0])); i++) { + dummy[i]++; + } +} + +static void * +high_load (void *unused) +{ + while (run) { + add(); + } + return NULL; +} + +static void * +do_signal (void *unused) +{ + while (run) { + kill (getpid(), SIGUSR1); + while (sem_wait(&sem) < 0 && errno == EINTR); + } + return NULL; +} + +/* See tcc-doc.info */ +#ifdef __BOUNDS_CHECKING_ON +extern void __bound_checking (int no_check); +#define BOUNDS_CHECKING_OFF __bound_checking(1) +#define BOUNDS_CHECKING_ON __bound_checking(-1) +#else +#define BOUNDS_CHECKING_OFF +#define BOUNDS_CHECKING_ON +#endif + +static void real_signal_handler(int sig) +{ + add(); + sem_post (&sem); +} + +static void signal_handler(int sig) +{ + BOUNDS_CHECKING_OFF; + real_signal_handler(sig); + BOUNDS_CHECKING_ON; +} + +int +main (void) +{ + int i; + pthread_t id1, id2; + struct sigaction act; + struct timespec request; + + memset (&act, 0, sizeof (act)); + act.sa_handler = signal_handler; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + sigaction (SIGUSR1, &act, NULL); + sem_init (&sem, 1, 0); + pthread_create(&id1, NULL, high_load, NULL); + pthread_create(&id2, NULL, do_signal, NULL); + clock_gettime (CLOCK_MONOTONIC, &request); + request.tv_sec += 1; + request.tv_nsec += 0; + printf ("start\n"); + while (clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &request, NULL)) { + } + printf ("end\n"); + run = 0; + pthread_join(id1, NULL); + pthread_join(id2, NULL); + sem_destroy (&sem); + return 0; +} diff --git a/tests/tests2/114_bound_signal.expect b/tests/tests2/114_bound_signal.expect new file mode 100644 index 0000000..5d0fb3b --- /dev/null +++ b/tests/tests2/114_bound_signal.expect @@ -0,0 +1,2 @@ +start +end diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index 5f3285c..9d3f360 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -25,6 +25,7 @@ endif ifeq (,$(filter i386 x86_64,$(ARCH))) SKIP += 85_asm-outside-function.test SKIP += 112_backtrace.test 113_btdll.test + SKIP += 114_bound_signal.test endif ifeq (-$(CONFIG_musl)-,-yes-) SKIP += 112_backtrace.test @@ -37,6 +38,7 @@ ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-) endif ifneq (-$(CONFIG_WIN32)$(CONFIG_WIN64)-,--) SKIP += 106_pthread.test # No pthread support + SKIP += 114_bound_signal.test endif # Some tests might need arguments @@ -86,6 +88,8 @@ GEN-ALWAYS = -bt $1 -shared -D DLL=2 -o a2$(DLLSUF) && $(TCC) \ -bt a1$(DLLSUF) a2$(DLLSUF) -Wl,-rpath=. +114_bound_signal.test: FLAGS += -b + # Filter source directory in warnings/errors (out-of-tree builds) FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' diff --git a/x86_64-gen.c b/x86_64-gen.c index 8eec6cb..1337ddd 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -1041,7 +1041,9 @@ void gfunc_epilog(void) loc = (loc & -16) - func_scratch; #ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) + if (tcc_state->do_bounds_check && + (func_bound_offset != lbounds_section->data_offset || + tcc_state->alloca_vla_used)) gen_bounds_epilog(); #endif @@ -1621,7 +1623,9 @@ void gfunc_epilog(void) int v, saved_ind; #ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) + if (tcc_state->do_bounds_check && + (func_bound_offset != lbounds_section->data_offset || + tcc_state->alloca_vla_used)) gen_bounds_epilog(); #endif o(0xc9); /* leave */