| @@ -111,16 +111,6 @@ ST_DATA struct temp_local_variable { · 110 unmodified lines |
| 111 | short align; | 111 | short align; |
| 112 | } arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER]; | 112 | } arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER]; |
| 113 | short nb_temp_local_vars; | 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 | static struct scope { | 115 | static struct scope { |
| 126 | struct scope *prev; | 116 | struct scope *prev; |
| @@ -1502,11 +1492,7 @@ static int get_temp_local_var(int size,int align){ · 1375 unmodified lines |
| 1502 | found=0; | 1492 | found=0; |
| 1503 | for(i=0;i<nb_temp_local_vars;i++){ | 1493 | for(i=0;i<nb_temp_local_vars;i++){ |
| 1504 | temp_var=&arr_temp_local_vars[i]; | 1494 | temp_var=&arr_temp_local_vars[i]; |
| 1505 | if(temp_var->size<size||align!=temp_var->align | 1495 | 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 | ){ | | |
| 1510 | continue; | 1496 | continue; |
| 1511 | } | 1497 | } |
| 1512 | /*check if temp_var is free*/ | 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) | 1596 | /* Add bounds for local symbols from S to E (via ->prev) */ |
| 1611 | { | 1597 | static void add_local_bounds(Sym *s, Sym *e) |
| 1612 | int i, j; | 1598 | { |
| 1613 | | 1599 | for (; s != e; s = s->prev) { |
| 1614 | if (call_nesting++ == 0) | 1600 | if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL) |
| 1615 | for (i = 1; i <= nb_args; ++i) | 1601 | continue; |
| 1616 | for (j = 0; j < nb_temp_local_vars; j++) | 1602 | /* Add arrays/structs/unions because we always take address */ |
| 1617 | if (vtop[1 - i].c.i == arr_temp_local_vars[j].location) { | 1603 | if ((s->type.t & VT_ARRAY) |
| 1618 | used_location[j] = 1; | 1604 | || (s->type.t & VT_BTYPE) == VT_STRUCT |
| 1619 | break; | 1605 | || s->a.addrtaken) { |
| 1620 | } | 1606 | /* add local bound info */ |
| 1621 | } | 1607 | int align, size = type_size(&s->type, &align); |
| 1622 | | 1608 | addr_t *bounds_ptr = section_ptr_add(lbounds_section, |
| 1623 | ST_FUNC void restore_temp_local() | 1609 | 2 * sizeof(addr_t)); |
| 1624 | { | 1610 | bounds_ptr[0] = s->c; |
| 1625 | if (--call_nesting == 0) | 1611 | bounds_ptr[1] = size; |
| 1626 | memset (used_location, 0, sizeof (used_location)); | 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; | 1620 | #ifdef CONFIG_TCC_BCHECK |
| 1632 | /* Add arrays/structs/unions because we always take address */ | 1621 | if (!keep && tcc_state->do_bounds_check) |
| 1633 | int taken = (type->t & VT_ARRAY) | 1622 | add_local_bounds(*ptop, b); |
| 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 | } | | |
| 1653 | #endif | 1623 | #endif |
| | 1624 | sym_pop(ptop, b, keep); |
| | 1625 | } |
| 1654 | | 1626 | |
| 1655 | static void incr_bf_adr(int o) | 1627 | static void incr_bf_adr(int o) |
| 1656 | { | 1628 | { |
| @@ -3690,11 +3662,11 @@ redo: · 2033 unmodified lines |
| 3690 | } | 3662 | } |
| 3691 | case TOK_CONSTRUCTOR1: | 3663 | case TOK_CONSTRUCTOR1: |
| 3692 | case TOK_CONSTRUCTOR2: | 3664 | case TOK_CONSTRUCTOR2: |
| 3693 | ad->a.constructor = 1; | 3665 | ad->constructor = 1; |
| 3694 | break; | 3666 | break; |
| 3695 | case TOK_DESTRUCTOR1: | 3667 | case TOK_DESTRUCTOR1: |
| 3696 | case TOK_DESTRUCTOR2: | 3668 | case TOK_DESTRUCTOR2: |
| 3697 | ad->a.destructor = 1; | 3669 | ad->destructor = 1; |
| 3698 | break; | 3670 | break; |
| 3699 | case TOK_SECTION1: | 3671 | case TOK_SECTION1: |
| 3700 | case TOK_SECTION2: | 3672 | case TOK_SECTION2: |
| @@ -5138,23 +5110,8 @@ ST_FUNC void unary(void) · 1437 unmodified lines |
| 5138 | if ((vtop->type.t & VT_BTYPE) != VT_FUNC && | 5110 | if ((vtop->type.t & VT_BTYPE) != VT_FUNC && |
| 5139 | !(vtop->type.t & VT_ARRAY)) | 5111 | !(vtop->type.t & VT_ARRAY)) |
| 5140 | test_lvalue(); | 5112 | test_lvalue(); |
| 5141 | #ifdef CONFIG_TCC_BCHECK | 5113 | if (vtop->sym) |
| 5142 | if (tcc_state->do_bounds_check && vtop->sym) { | 5114 | vtop->sym->a.addrtaken = 1; |
| 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 | | |
| 5158 | mk_pointer(&vtop->type); | 5115 | mk_pointer(&vtop->type); |
| 5159 | gaddrof(); | 5116 | gaddrof(); |
| 5160 | break; | 5117 | break; |
| @@ -6454,7 +6411,7 @@ void prev_scope(struct scope *o, int is_expr) · 1293 unmodified lines |
| 6454 | tables, though. sym_pop will do that. */ | 6411 | tables, though. sym_pop will do that. */ |
| 6455 | | 6412 | |
| 6456 | /* pop locally defined symbols */ | 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 | cur_scope = o->prev; | 6416 | cur_scope = o->prev; |
| 6460 | --local_scope; | 6417 | --local_scope; |
| @@ -7426,17 +7383,13 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 965 unmodified lines |
| 7426 | Sym *sym = NULL; | 7383 | Sym *sym = NULL; |
| 7427 | int saved_nocode_wanted = nocode_wanted; | 7384 | int saved_nocode_wanted = nocode_wanted; |
| 7428 | #ifdef CONFIG_TCC_BCHECK | 7385 | #ifdef CONFIG_TCC_BCHECK |
| 7429 | int bcheck; | 7386 | int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED; |
| 7430 | #endif | 7387 | #endif |
| 7431 | | 7388 | |
| 7432 | /* Always allocate static or global variables */ | 7389 | /* Always allocate static or global variables */ |
| 7433 | if (v && (r & VT_VALMASK) == VT_CONST) | 7390 | if (v && (r & VT_VALMASK) == VT_CONST) |
| 7434 | nocode_wanted |= 0x80000000; | 7391 | nocode_wanted |= 0x80000000; |
| 7435 | | 7392 | |
| 7436 | #ifdef CONFIG_TCC_BCHECK | | |
| 7437 | bcheck = tcc_state->do_bounds_check && !NODATA_WANTED; | | |
| 7438 | #endif | | |
| 7439 | | | |
| 7440 | flexible_array = NULL; | 7393 | flexible_array = NULL; |
| 7441 | if ((type->t & VT_BTYPE) == VT_STRUCT) { | 7394 | if ((type->t & VT_BTYPE) == VT_STRUCT) { |
| 7442 | Sym *field = type->ref->next; | 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 | sec = NULL; | 7461 | sec = NULL; |
| 7509 | #ifdef CONFIG_TCC_BCHECK | 7462 | #ifdef CONFIG_TCC_BCHECK |
| 7510 | if (bcheck && v) { | 7463 | if (bcheck && v) { |
| 7511 | /* add padding between stack variables */ | 7464 | /* add padding between stack variables for bound checking */ |
| 7512 | loc--; | 7465 | loc--; |
| 7513 | } | 7466 | } |
| 7514 | #endif | 7467 | #endif |
| 7515 | loc = (loc - size) & -align; | 7468 | loc = (loc - size) & -align; |
| 7516 | addr = loc; | 7469 | addr = loc; |
| 7517 | #ifdef CONFIG_TCC_BCHECK | 7470 | #ifdef CONFIG_TCC_BCHECK |
| 7518 | /* handles bounds */ | | |
| 7519 | if (bcheck && v) { | 7471 | if (bcheck && v) { |
| 7520 | add_bound_param (type, size, v, addr); | 7472 | /* add padding between stack variables for bound checking */ |
| 7521 | /* add padding between stack variables */ | | |
| 7522 | loc--; | 7473 | loc--; |
| 7523 | } | 7474 | } |
| 7524 | #endif | 7475 | #endif |
| @@ -7682,10 +7633,10 @@ static void gen_function(Sym *sym, AttributeDef *ad) · 157 unmodified lines |
| 7682 | /* NOTE: we patch the symbol size later */ | 7633 | /* NOTE: we patch the symbol size later */ |
| 7683 | put_extern_sym(sym, cur_text_section, ind, 0); | 7634 | put_extern_sym(sym, cur_text_section, ind, 0); |
| 7684 | | 7635 | |
| 7685 | if (ad && ad->a.constructor) { | 7636 | if (ad && ad->constructor) { |
| 7686 | add_init_array (tcc_state, sym); | 7637 | add_init_array (tcc_state, sym); |
| 7687 | } | 7638 | } |
| 7688 | if (ad && ad->a.destructor) { | 7639 | if (ad && ad->destructor) { |
| 7689 | add_fini_array (tcc_state, sym); | 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 | sym_push2(&local_stack, SYM_FIELD, 0, 0); | 7649 | sym_push2(&local_stack, SYM_FIELD, 0, 0); |
| 7699 | local_scope = 1; /* for function parameters */ | 7650 | local_scope = 1; /* for function parameters */ |
| 7700 | gfunc_prolog(sym); | 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 | local_scope = 0; | 7652 | local_scope = 0; |
| 7721 | rsym = 0; | 7653 | rsym = 0; |
| 7722 | clear_temp_local_var_list(); | 7654 | clear_temp_local_var_list(); |
| 7723 | block(0); | 7655 | block(0); |
| 7724 | gsym(rsym); | 7656 | gsym(rsym); |
| 7725 | nocode_wanted = 0; | 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 | gfunc_epilog(); | 7658 | gfunc_epilog(); |
| 7748 | cur_text_section->data_offset = ind; | 7659 | cur_text_section->data_offset = ind; |
| 7749 | /* reset local stack */ | 7660 | /* reset local stack */ |
| 7750 | sym_pop(&local_stack, NULL, 0); | 7661 | pop_local_syms(&local_stack, NULL, 0); |
| 7751 | local_scope = 0; | 7662 | local_scope = 0; |
| 7752 | label_pop(&global_label_stack, NULL, 0); | 7663 | label_pop(&global_label_stack, NULL, 0); |
| 7753 | sym_pop(&all_cleanups, NULL, 0); | 7664 | sym_pop(&all_cleanups, NULL, 0); |