tccgen.c: - Fix 'tcc -b conftest.s' - Add offset during bound checking for struct return lib/bcheck.c: - Check overlap when reusing vla/alloca arm-gen.c: arm64-gen.c: riscv64-gen.c: lib/alloca86-bt.S: - add space for vla/alloca during bound checking tests/tests2/Makefile: tests/tests2/121_struct_return: tests/tests2/122_vla_reuse: - New test cases with bound checking enabled to test vla and struct return
Unified · Split
| @@ -2255,6 +2255,10 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2254 unmodified lines | |||
| 2255 | vpushv(vtop); | 2255 | vpushv(vtop); |
| 2256 | #endif | 2256 | #endif |
| 2257 | r = intr(gv(RC_INT)); | 2257 | r = intr(gv(RC_INT)); |
| 2258 | #if defined(CONFIG_TCC_BCHECK) | ||
| 2259 | if (tcc_state->do_bounds_check) | ||
| 2260 | o(0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */ | ||
| 2261 | #endif | ||
| 2258 | o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */ | 2262 | o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */ |
| 2259 | #ifdef TCC_ARM_EABI | 2263 | #ifdef TCC_ARM_EABI |
| 2260 | if (align < 8) | 2264 | if (align < 8) |
| @@ -2046,6 +2046,11 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2045 unmodified lines | |||
| 2046 | vpushv(vtop); | 2046 | vpushv(vtop); |
| 2047 | #endif | 2047 | #endif |
| 2048 | r = intr(gv(RC_INT)); | 2048 | r = intr(gv(RC_INT)); |
| 2049 | #if defined(CONFIG_TCC_BCHECK) | ||
| 2050 | if (tcc_state->do_bounds_check) | ||
| 2051 | o(0x91004000 | r | r << 5); // add x(r),x(r),#15+1 | ||
| 2052 | else | ||
| 2053 | #endif | ||
| 2049 | o(0x91003c00 | r | r << 5); // add x(r),x(r),#15 | 2054 | o(0x91003c00 | r | r << 5); // add x(r),x(r),#15 |
| 2050 | o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15 | 2055 | o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15 |
| 2051 | o(0xcb2063ff | r << 16); // sub sp,sp,x(r) | 2056 | o(0xcb2063ff | r << 16); // sub sp,sp,x(r) |
| @@ -12,7 +12,7 @@ _(__bound_alloca): · 11 unmodified lines | |||
| 12 | pop %edx | 12 | pop %edx |
| 13 | pop %eax | 13 | pop %eax |
| 14 | mov %eax, %ecx | 14 | mov %eax, %ecx |
| 15 | add $3,%eax | 15 | add $3+1,%eax |
| 16 | and $-4,%eax | 16 | and $-4,%eax |
| 17 | jz p6 | 17 | jz p6 |
| 18 | 18 | ||
| @@ -212,6 +212,7 @@ struct tree_node { · 211 unmodified lines | |||
| 212 | typedef struct alloca_list_struct { | 212 | typedef struct alloca_list_struct { |
| 213 | size_t fp; | 213 | size_t fp; |
| 214 | void *p; | 214 | void *p; |
| 215 | size_t size; | ||
| 215 | struct alloca_list_struct *next; | 216 | struct alloca_list_struct *next; |
| 216 | } alloca_list_type; | 217 | } alloca_list_type; |
| 217 | 218 | ||
| @@ -728,12 +729,22 @@ void __bound_new_region(void *p, size_t size) · 510 unmodified lines | |||
| 728 | last = NULL; | 729 | last = NULL; |
| 729 | cur = alloca_list; | 730 | cur = alloca_list; |
| 730 | while (cur) { | 731 | while (cur) { |
| 731 | if (cur->fp == fp && cur->p == p) { | 732 | #if defined(__i386__) || (defined(__arm__) && !defined(TCC_ARM_EABI)) |
| 733 | int align = 4; | ||
| 734 | #elif defined(__arm__) | ||
| 735 | int align = 8; | ||
| 736 | #else | ||
| 737 | int align = 16; | ||
| 738 | #endif | ||
| 739 | void *cure = (void *)((char *)cur->p + ((cur->size + align) & -align)); | ||
| 740 | void *pe = (void *)((char *)p + ((size + align) & -align)); | ||
| 741 | if (cur->fp == fp && ((cur->p <= p && cure > p) || | ||
| 742 | (p <= cur->p && pe > cur->p))) { | ||
| 732 | if (last) | 743 | if (last) |
| 733 | last->next = cur->next; | 744 | last->next = cur->next; |
| 734 | else | 745 | else |
| 735 | alloca_list = cur->next; | 746 | alloca_list = cur->next; |
| 736 | tree = splay_delete((size_t)p, tree); | 747 | tree = splay_delete((size_t)cur->p, tree); |
| 737 | break; | 748 | break; |
| 738 | } | 749 | } |
| 739 | last = cur; | 750 | last = cur; |
| @@ -743,6 +754,7 @@ void __bound_new_region(void *p, size_t size) · 3 unmodified lines | |||
| 743 | if (new) { | 754 | if (new) { |
| 744 | new->fp = fp; | 755 | new->fp = fp; |
| 745 | new->p = p; | 756 | new->p = p; |
| 757 | new->size = size; | ||
| 746 | new->next = alloca_list; | 758 | new->next = alloca_list; |
| 747 | alloca_list = new; | 759 | alloca_list = new; |
| 748 | } | 760 | } |
| @@ -1327,6 +1327,11 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) · 1326 unmodified lines | |||
| 1327 | vpushv(vtop); | 1327 | vpushv(vtop); |
| 1328 | #endif | 1328 | #endif |
| 1329 | rr = ireg(gv(RC_INT)); | 1329 | rr = ireg(gv(RC_INT)); |
| 1330 | #if defined(CONFIG_TCC_BCHECK) | ||
| 1331 | if (tcc_state->do_bounds_check) | ||
| 1332 | EI(0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+1 | ||
| 1333 | else | ||
| 1334 | #endif | ||
| 1330 | EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15 | 1335 | EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15 |
| 1331 | EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16 | 1336 | EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16 |
| 1332 | ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr | 1337 | ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr |
| @@ -413,7 +413,8 @@ ST_FUNC void tcc_debug_start(TCCState *s1) · 412 unmodified lines | |||
| 413 | pstrcat(buf, sizeof(buf), "/"); | 413 | pstrcat(buf, sizeof(buf), "/"); |
| 414 | put_stabs_r(s1, buf, N_SO, 0, 0, | 414 | put_stabs_r(s1, buf, N_SO, 0, 0, |
| 415 | text_section->data_offset, text_section, section_sym); | 415 | text_section->data_offset, text_section, section_sym); |
| 416 | put_stabs_r(s1, file->prev->filename, N_SO, 0, 0, | 416 | put_stabs_r(s1, file->prev ? file->prev->filename : file->filename, |
| 417 | N_SO, 0, 0, | ||
| 417 | text_section->data_offset, text_section, section_sym); | 418 | text_section->data_offset, text_section, section_sym); |
| 418 | for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++) | 419 | for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++) |
| 419 | put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0); | 420 | put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0); |
| @@ -6100,6 +6101,9 @@ special_math_val: · 5680 unmodified lines | |||
| 6100 | /* pass it as 'int' to avoid structure arg passing | 6101 | /* pass it as 'int' to avoid structure arg passing |
| 6101 | problems */ | 6102 | problems */ |
| 6102 | vseti(VT_LOCAL, loc); | 6103 | vseti(VT_LOCAL, loc); |
| 6104 | #ifdef CONFIG_TCC_BCHECK | ||
| 6105 | loc -= tcc_state->do_bounds_check != 0; | ||
| 6106 | #endif | ||
| 6103 | ret.c = vtop->c; | 6107 | ret.c = vtop->c; |
| 6104 | if (ret_nregs < 0) | 6108 | if (ret_nregs < 0) |
| 6105 | vtop--; | 6109 | vtop--; |
| @@ -0,0 +1,35 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | typedef struct { | ||
| 4 | int data[4]; | ||
| 5 | double d1; | ||
| 6 | double d2; | ||
| 7 | } Node; | ||
| 8 | |||
| 9 | Node init(Node self) { | ||
| 10 | self.data[0] = 0; | ||
| 11 | self.data[1] = 1; | ||
| 12 | self.data[2] = 2; | ||
| 13 | self.data[3] = 3; | ||
| 14 | self.d1 = 1234; | ||
| 15 | self.d2 = 2345; | ||
| 16 | return self; | ||
| 17 | } | ||
| 18 | |||
| 19 | void dummy(Node self) { | ||
| 20 | } | ||
| 21 | |||
| 22 | void print_data(Node data) { | ||
| 23 | printf ("%d %d %d %d %g %g\n", | ||
| 24 | data.data[0], data.data[1], data.data[2], data.data[3], | ||
| 25 | data.d1, data.d2); | ||
| 26 | } | ||
| 27 | |||
| 28 | int main(void) { | ||
| 29 | /* This code resulted in a bounds checking error */ | ||
| 30 | Node data; | ||
| 31 | dummy (data); | ||
| 32 | char val; | ||
| 33 | data = init (data); | ||
| 34 | print_data(data); | ||
| 35 | } | ||
| @@ -0,0 +1 @@ | |||
| 1 | 0 1 2 3 1234 2345 | ||
| @@ -0,0 +1,31 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | int | ||
| 4 | main (void) | ||
| 5 | { | ||
| 6 | int n = 0; | ||
| 7 | int first=1; | ||
| 8 | int *p[101]; | ||
| 9 | if (0) { | ||
| 10 | lab:; | ||
| 11 | } | ||
| 12 | int x[n % 100 + 1]; | ||
| 13 | if (first == 0) { | ||
| 14 | if (&x[0] != p[n % 100 + 1]) { | ||
| 15 | printf ("ERROR: %d %p $p\n", &x[0], p[n % 100 + 1]); | ||
| 16 | return(1); | ||
| 17 | } | ||
| 18 | } | ||
| 19 | else { | ||
| 20 | p[n % 100 + 1] = &x[0]; | ||
| 21 | first = n < 100; | ||
| 22 | } | ||
| 23 | x[0] = 1; | ||
| 24 | x[n % 100] = 2; | ||
| 25 | n++; | ||
| 26 | if (n < 100000) | ||
| 27 | goto lab; | ||
| 28 | printf ("OK\n"); | ||
| 29 | return 0; | ||
| 30 | } | ||
| 31 | |||
| @@ -0,0 +1 @@ | |||
| 1 | OK | ||
| @@ -103,6 +103,8 @@ GEN-ALWAYS = · 102 unmodified lines | |||
| 103 | 115_bound_setjmp.test: FLAGS += -b | 103 | 115_bound_setjmp.test: FLAGS += -b |
| 104 | 116_bound_setjmp2.test: FLAGS += -b | 104 | 116_bound_setjmp2.test: FLAGS += -b |
| 105 | 117_builtins.test: T1 = ( $(TCC) -run $1 && $(TCC) -b -run $1 ) | 105 | 117_builtins.test: T1 = ( $(TCC) -run $1 && $(TCC) -b -run $1 ) |
| 106 | 121_struct_return.test: FLAGS += -b | ||
| 107 | 122_vla_reuse.test: FLAGS += -b | ||
| 106 | 108 | ||
| 107 | # Filter source directory in warnings/errors (out-of-tree builds) | 109 | # Filter source directory in warnings/errors (out-of-tree builds) |
| 108 | FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' | 110 | FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' |