Allow signal handlers when bound checking

Disable generating bound_local_new/bound_local_delete when not needed.
Add new testcase 114_bound_signal.
This commit is contained in:
herman ten brugge 2020-05-05 08:31:57 +02:00
parent 973a14bb2f
commit 8370bc03a1
8 changed files with 125 additions and 13 deletions

View File

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

View File

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

1
tcc.h
View File

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

View File

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

View File

@ -0,0 +1,94 @@
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
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;
}

View File

@ -0,0 +1,2 @@
start
end

View File

@ -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'

View File

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