| @@ -111,16 +111,6 @@ ST_DATA struct temp_local_variable { · 110 unmodified lines |
| 111 | 111 | short align; |
| 112 | 112 | } arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER]; |
| 113 | 113 | short nb_temp_local_vars; |
| 114 | | −#ifdef CONFIG_TCC_BCHECK |
| 115 | | −static short call_nesting; |
| 116 | | −static char used_location[MAX_TEMP_LOCAL_VARIABLE_NUMBER]; |
| 117 | | −static int nb_bound_local_param; |
| 118 | | −struct { |
| 119 | | − unsigned long data_offset; |
| 120 | | − int v; |
| 121 | | −} *bound_local_param; |
| 122 | | −ST_DATA addr_t func_bound_offset; |
| 123 | | −#endif |
| 124 | 114 | |
| 125 | 115 | static struct scope { |
| 126 | 116 | struct scope *prev; |
| @@ -1502,11 +1492,7 @@ static int get_temp_local_var(int size,int align){ · 1375 unmodified lines |
| 1502 | 1492 | found=0; |
| 1503 | 1493 | for(i=0;i<nb_temp_local_vars;i++){ |
| 1504 | 1494 | temp_var=&arr_temp_local_vars[i]; |
| 1505 | | − if(temp_var->size<size||align!=temp_var->align |
| 1506 | | −#ifdef CONFIG_TCC_BCHECK |
| 1507 | | − || (tcc_state->do_bounds_check && used_location[i]) |
| 1508 | | −#endif |
| 1509 | | − ){ |
| 1495 | + if(temp_var->size<size||align!=temp_var->align){ |
| 1510 | 1496 | continue; |
| 1511 | 1497 | } |
| 1512 | 1498 | /*check if temp_var is free*/ |
| @@ -1607,50 +1593,36 @@ ST_FUNC void gbound_args(int nb_args) · 94 unmodified lines |
| 1607 | 1593 | } |
| 1608 | 1594 | } |
| 1609 | 1595 | |
| 1610 | | −ST_FUNC void save_temp_local(int nb_args) |
| 1611 | | −{ |
| 1612 | | − int i, j; |
| 1613 | | − |
| 1614 | | − if (call_nesting++ == 0) |
| 1615 | | − for (i = 1; i <= nb_args; ++i) |
| 1616 | | − for (j = 0; j < nb_temp_local_vars; j++) |
| 1617 | | − if (vtop[1 - i].c.i == arr_temp_local_vars[j].location) { |
| 1618 | | − used_location[j] = 1; |
| 1619 | | − break; |
| 1620 | | − } |
| 1621 | | −} |
| 1622 | | − |
| 1623 | | −ST_FUNC void restore_temp_local() |
| 1624 | | −{ |
| 1625 | | − if (--call_nesting == 0) |
| 1626 | | − memset (used_location, 0, sizeof (used_location)); |
| 1596 | +/* Add bounds for local symbols from S to E (via ->prev) */ |
| 1597 | +static void add_local_bounds(Sym *s, Sym *e) |
| 1598 | +{ |
| 1599 | + for (; s != e; s = s->prev) { |
| 1600 | + if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL) |
| 1601 | + continue; |
| 1602 | + /* Add arrays/structs/unions because we always take address */ |
| 1603 | + if ((s->type.t & VT_ARRAY) |
| 1604 | + || (s->type.t & VT_BTYPE) == VT_STRUCT |
| 1605 | + || s->a.addrtaken) { |
| 1606 | + /* add local bound info */ |
| 1607 | + int align, size = type_size(&s->type, &align); |
| 1608 | + addr_t *bounds_ptr = section_ptr_add(lbounds_section, |
| 1609 | + 2 * sizeof(addr_t)); |
| 1610 | + bounds_ptr[0] = s->c; |
| 1611 | + bounds_ptr[1] = size; |
| 1612 | + } |
| 1613 | + } |
| 1627 | 1614 | } |
| 1615 | +#endif |
| 1628 | 1616 | |
| 1629 | | −static void add_bound_param(CType *type, int size, int v, int c) |
| 1617 | +/* Wrapper around sym_pop, that potentially also registers local bounds. */ |
| 1618 | +static void pop_local_syms(Sym **ptop, Sym *b, int keep) |
| 1630 | 1619 | { |
| 1631 | | − addr_t *bounds_ptr; |
| 1632 | | − /* Add arrays/structs/unions because we always take address */ |
| 1633 | | − int taken = (type->t & VT_ARRAY) |
| 1634 | | − || (type->t & VT_BTYPE) == VT_STRUCT; |
| 1635 | | − |
| 1636 | | − if (taken == 0) { |
| 1637 | | − /* Add parameter to check */ |
| 1638 | | − nb_bound_local_param++; |
| 1639 | | − bound_local_param = |
| 1640 | | − tcc_realloc (bound_local_param, |
| 1641 | | − nb_bound_local_param * |
| 1642 | | − sizeof (*bound_local_param)); |
| 1643 | | − bound_local_param[nb_bound_local_param-1].data_offset = |
| 1644 | | − lbounds_section->data_offset; |
| 1645 | | − bound_local_param[nb_bound_local_param-1].v = v; |
| 1646 | | − } |
| 1647 | | − /* add local bound info */ |
| 1648 | | − bounds_ptr = section_ptr_add(lbounds_section, |
| 1649 | | − 2 * sizeof(addr_t)); |
| 1650 | | − bounds_ptr[0] = c; |
| 1651 | | − bounds_ptr[1] = taken ? size : ~size; |
| 1652 | | −} |
| 1620 | +#ifdef CONFIG_TCC_BCHECK |
| 1621 | + if (!keep && tcc_state->do_bounds_check) |
| 1622 | + add_local_bounds(*ptop, b); |
| 1653 | 1623 | #endif |
| 1624 | + sym_pop(ptop, b, keep); |
| 1625 | +} |
| 1654 | 1626 | |
| 1655 | 1627 | static void incr_bf_adr(int o) |
| 1656 | 1628 | { |
| @@ -3690,11 +3662,11 @@ redo: · 2033 unmodified lines |
| 3690 | 3662 | } |
| 3691 | 3663 | case TOK_CONSTRUCTOR1: |
| 3692 | 3664 | case TOK_CONSTRUCTOR2: |
| 3693 | | − ad->a.constructor = 1; |
| 3665 | + ad->constructor = 1; |
| 3694 | 3666 | break; |
| 3695 | 3667 | case TOK_DESTRUCTOR1: |
| 3696 | 3668 | case TOK_DESTRUCTOR2: |
| 3697 | | − ad->a.destructor = 1; |
| 3669 | + ad->destructor = 1; |
| 3698 | 3670 | break; |
| 3699 | 3671 | case TOK_SECTION1: |
| 3700 | 3672 | case TOK_SECTION2: |
| @@ -5138,23 +5110,8 @@ ST_FUNC void unary(void) · 1437 unmodified lines |
| 5138 | 5110 | if ((vtop->type.t & VT_BTYPE) != VT_FUNC && |
| 5139 | 5111 | !(vtop->type.t & VT_ARRAY)) |
| 5140 | 5112 | test_lvalue(); |
| 5141 | | −#ifdef CONFIG_TCC_BCHECK |
| 5142 | | − if (tcc_state->do_bounds_check && vtop->sym) { |
| 5143 | | − int i; |
| 5144 | | − |
| 5145 | | − /* Mark parameter as being used for address off */ |
| 5146 | | − for (i = 0; i < nb_bound_local_param; i++) { |
| 5147 | | − if (bound_local_param[i].v == vtop->sym->v) { |
| 5148 | | − addr_t *bounds_ptr = |
| 5149 | | − (addr_t *) (lbounds_section->data + |
| 5150 | | − bound_local_param[i].data_offset); |
| 5151 | | − bounds_ptr[1] = ~bounds_ptr[1]; |
| 5152 | | − bound_local_param[i].v = 0; |
| 5153 | | − break; |
| 5154 | | − } |
| 5155 | | − } |
| 5156 | | − } |
| 5157 | | −#endif |
| 5113 | + if (vtop->sym) |
| 5114 | + vtop->sym->a.addrtaken = 1; |
| 5158 | 5115 | mk_pointer(&vtop->type); |
| 5159 | 5116 | gaddrof(); |
| 5160 | 5117 | break; |
| @@ -6454,7 +6411,7 @@ void prev_scope(struct scope *o, int is_expr) · 1293 unmodified lines |
| 6454 | 6411 | tables, though. sym_pop will do that. */ |
| 6455 | 6412 | |
| 6456 | 6413 | /* pop locally defined symbols */ |
| 6457 | | − sym_pop(&local_stack, o->lstk, is_expr); |
| 6414 | + pop_local_syms(&local_stack, o->lstk, is_expr); |
| 6458 | 6415 | |
| 6459 | 6416 | cur_scope = o->prev; |
| 6460 | 6417 | --local_scope; |
| @@ -7426,17 +7383,13 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 965 unmodified lines |
| 7426 | 7383 | Sym *sym = NULL; |
| 7427 | 7384 | int saved_nocode_wanted = nocode_wanted; |
| 7428 | 7385 | #ifdef CONFIG_TCC_BCHECK |
| 7429 | | − int bcheck; |
| 7386 | + int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED; |
| 7430 | 7387 | #endif |
| 7431 | 7388 | |
| 7432 | 7389 | /* Always allocate static or global variables */ |
| 7433 | 7390 | if (v && (r & VT_VALMASK) == VT_CONST) |
| 7434 | 7391 | nocode_wanted |= 0x80000000; |
| 7435 | 7392 | |
| 7436 | | −#ifdef CONFIG_TCC_BCHECK |
| 7437 | | − bcheck = tcc_state->do_bounds_check && !NODATA_WANTED; |
| 7438 | | −#endif |
| 7439 | | − |
| 7440 | 7393 | flexible_array = NULL; |
| 7441 | 7394 | if ((type->t & VT_BTYPE) == VT_STRUCT) { |
| 7442 | 7395 | Sym *field = type->ref->next; |
| @@ -7508,17 +7461,15 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 65 unmodified lines |
| 7508 | 7461 | sec = NULL; |
| 7509 | 7462 | #ifdef CONFIG_TCC_BCHECK |
| 7510 | 7463 | if (bcheck && v) { |
| 7511 | | − /* add padding between stack variables */ |
| 7464 | + /* add padding between stack variables for bound checking */ |
| 7512 | 7465 | loc--; |
| 7513 | 7466 | } |
| 7514 | 7467 | #endif |
| 7515 | 7468 | loc = (loc - size) & -align; |
| 7516 | 7469 | addr = loc; |
| 7517 | 7470 | #ifdef CONFIG_TCC_BCHECK |
| 7518 | | − /* handles bounds */ |
| 7519 | 7471 | if (bcheck && v) { |
| 7520 | | − add_bound_param (type, size, v, addr); |
| 7521 | | − /* add padding between stack variables */ |
| 7472 | + /* add padding between stack variables for bound checking */ |
| 7522 | 7473 | loc--; |
| 7523 | 7474 | } |
| 7524 | 7475 | #endif |
| @@ -7682,10 +7633,10 @@ static void gen_function(Sym *sym, AttributeDef *ad) · 157 unmodified lines |
| 7682 | 7633 | /* NOTE: we patch the symbol size later */ |
| 7683 | 7634 | put_extern_sym(sym, cur_text_section, ind, 0); |
| 7684 | 7635 | |
| 7685 | | − if (ad && ad->a.constructor) { |
| 7636 | + if (ad && ad->constructor) { |
| 7686 | 7637 | add_init_array (tcc_state, sym); |
| 7687 | 7638 | } |
| 7688 | | − if (ad && ad->a.destructor) { |
| 7639 | + if (ad && ad->destructor) { |
| 7689 | 7640 | add_fini_array (tcc_state, sym); |
| 7690 | 7641 | } |
| 7691 | 7642 | |
| @@ -7698,56 +7649,16 @@ static void gen_function(Sym *sym, AttributeDef *ad) · 6 unmodified lines |
| 7698 | 7649 | sym_push2(&local_stack, SYM_FIELD, 0, 0); |
| 7699 | 7650 | local_scope = 1; /* for function parameters */ |
| 7700 | 7651 | gfunc_prolog(sym); |
| 7701 | | −#ifdef CONFIG_TCC_BCHECK |
| 7702 | | − if (tcc_state->do_bounds_check |
| 7703 | | − && sym->type.ref->f.func_type != FUNC_ELLIPSIS) { |
| 7704 | | − Sym *fpar; |
| 7705 | | − |
| 7706 | | − /* Add function arguments in case & is used */ |
| 7707 | | − for (fpar = sym->type.ref->next; fpar; fpar = fpar->next) { |
| 7708 | | − Sym *fsym = sym_find (fpar->v & ~SYM_FIELD); |
| 7709 | | − |
| 7710 | | − if (fsym && (fsym->r & VT_VALMASK) == VT_LOCAL) { |
| 7711 | | − int align; |
| 7712 | | − int size = type_size(&fsym->type, &align); |
| 7713 | | − |
| 7714 | | − if (size > 0) |
| 7715 | | − add_bound_param (&fsym->type, size, fsym->v, fsym->c); |
| 7716 | | − } |
| 7717 | | − } |
| 7718 | | − } |
| 7719 | | −#endif |
| 7720 | 7652 | local_scope = 0; |
| 7721 | 7653 | rsym = 0; |
| 7722 | 7654 | clear_temp_local_var_list(); |
| 7723 | 7655 | block(0); |
| 7724 | 7656 | gsym(rsym); |
| 7725 | 7657 | nocode_wanted = 0; |
| 7726 | | −#ifdef CONFIG_TCC_BCHECK |
| 7727 | | − if (tcc_state->do_bounds_check) { |
| 7728 | | − addr_t o = func_bound_offset; |
| 7729 | | − |
| 7730 | | − /* Remove parameters where address off is not used */ |
| 7731 | | − while (o != lbounds_section->data_offset) { |
| 7732 | | − addr_t *bounds_ptr = (addr_t *) (lbounds_section->data + o); |
| 7733 | | − if ((ssize_t) bounds_ptr[1] < 0) { |
| 7734 | | − lbounds_section->data_offset -= 2 * sizeof (addr_t); |
| 7735 | | − memmove(bounds_ptr, bounds_ptr + 2, |
| 7736 | | − lbounds_section->data_offset - o); |
| 7737 | | − } |
| 7738 | | − else { |
| 7739 | | − o += 2 * sizeof (addr_t); |
| 7740 | | − } |
| 7741 | | − } |
| 7742 | | − tcc_free (bound_local_param); |
| 7743 | | − nb_bound_local_param = 0; |
| 7744 | | − bound_local_param = NULL; |
| 7745 | | − } |
| 7746 | | −#endif |
| 7747 | 7658 | gfunc_epilog(); |
| 7748 | 7659 | cur_text_section->data_offset = ind; |
| 7749 | 7660 | /* reset local stack */ |
| 7750 | | − sym_pop(&local_stack, NULL, 0); |
| 7661 | + pop_local_syms(&local_stack, NULL, 0); |
| 7751 | 7662 | local_scope = 0; |
| 7752 | 7663 | label_pop(&global_label_stack, NULL, 0); |
| 7753 | 7664 | sym_pop(&all_cleanups, NULL, 0); |