diff --git a/lib/bcheck.c b/lib/bcheck.c index 1e90aa9..a338caa 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -449,7 +449,7 @@ void FASTCALL __bound_local_new(void *p1) dprintf(stderr, "%s, %s(): p1=%p fp=%p\n", __FILE__, __FUNCTION__, p, (void *)fp); WAIT_SEM (); - while ((addr = p[0])) { + while ((addr = p[0]) > 1) { INCR_COUNT(bound_local_new_count); tree = splay_insert(addr + fp, p[1], tree); p += 2; @@ -486,33 +486,32 @@ void FASTCALL __bound_local_delete(void *p1) dprintf(stderr, "%s, %s(): p1=%p fp=%p\n", __FILE__, __FUNCTION__, p, (void *)fp); WAIT_SEM (); - while ((addr = p[0])) { + while ((addr = p[0]) > 1) { INCR_COUNT(bound_local_delete_count); tree = splay_delete(addr + fp, tree); p += 2; } - { - alloca_list_type *last = NULL; - alloca_list_type *cur = alloca_list; - - while (cur) { - if (cur->fp == fp) { - if (last) - last->next = cur->next; - else - alloca_list = cur->next; - tree = splay_delete ((size_t) cur->p, tree); - cur->next = free_list; - free_list = cur; - cur = last ? last->next : alloca_list; - } - else { - last = cur; - cur = cur->next; - } + if (addr == 1) { + alloca_list_type *last = NULL; + alloca_list_type *cur = alloca_list; + + while (cur) { + if (cur->fp == fp) { + if (last) + last->next = cur->next; + else + alloca_list = cur->next; + tree = splay_delete ((size_t) cur->p, tree); + cur->next = free_list; + free_list = cur; + cur = last ? last->next : alloca_list; + } + else { + last = cur; + cur = cur->next; } + } } - POST_SEM (); while (free_list) { alloca_list_type *next = free_list->next; diff --git a/tccgen.c b/tccgen.c index 71d3d04..8a5cc6c 100644 --- a/tccgen.c +++ b/tccgen.c @@ -46,6 +46,7 @@ static int local_scope; static int in_sizeof; static int in_generic; static int section_sym; +static int alloc_vla_used; ST_DATA SValue *vtop; static SValue _vstack[1 + VSTACK_SIZE]; @@ -1621,6 +1622,20 @@ static void pop_local_syms(Sym **ptop, Sym *b, int keep, int ellipsis) sym_pop(ptop, b, keep); } +static void bound_add_alloc_vla(void) +{ +#ifdef CONFIG_TCC_BCHECK + if (tcc_state->do_bounds_check && alloc_vla_used) { + addr_t *bounds_ptr; + + /* Make sure __bound_local_delete is called */ + bounds_ptr = section_ptr_add(lbounds_section, 4 * sizeof(addr_t)); + bounds_ptr[0] = 1; /* marks alloca/vla used */ + bounds_ptr[1] = 0; + } +#endif +} + static void incr_bf_adr(int o) { vtop->type = char_pointer_type; @@ -5545,6 +5560,10 @@ special_math_val: Sym *sa; int nb_args, ret_nregs, ret_align, regsize, variadic; +#ifdef CONFIG_TCC_BCHECK + alloc_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) */ @@ -7580,6 +7599,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 + alloc_vla_used |= bcheck; +#endif } else if (has_init) { size_t oldreloc_offset = 0; if (sec && sec->reloc) @@ -7612,6 +7634,7 @@ static void gen_function(Sym *sym) cur_scope = root_scope = &f; nocode_wanted = 0; + alloc_vla_used = 0; ind = cur_text_section->data_offset; if (sym->a.aligned) { size_t newoff = section_add(cur_text_section, 0, @@ -7641,6 +7664,7 @@ static void gen_function(Sym *sym) /* reset local stack */ pop_local_syms(&local_stack, NULL, 0, sym->type.ref->f.func_type == FUNC_ELLIPSIS); + bound_add_alloc_vla(); gfunc_epilog(); cur_text_section->data_offset = ind; local_scope = 0;