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 | 2255 | vpushv(vtop); |
| 2256 | 2256 | #endif |
| 2257 | 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 | 2262 | o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */ |
| 2259 | 2263 | #ifdef TCC_ARM_EABI |
| 2260 | 2264 | if (align < 8) |
| @@ -2046,6 +2046,11 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2045 unmodified lines | ||
| 2046 | 2046 | vpushv(vtop); |
| 2047 | 2047 | #endif |
| 2048 | 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 | 2054 | o(0x91003c00 | r | r << 5); // add x(r),x(r),#15 |
| 2050 | 2055 | o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15 |
| 2051 | 2056 | o(0xcb2063ff | r << 16); // sub sp,sp,x(r) |
| @@ -12,7 +12,7 @@ _(__bound_alloca): · 11 unmodified lines | ||
| 12 | 12 | pop %edx |
| 13 | 13 | pop %eax |
| 14 | 14 | mov %eax, %ecx |
| 15 | − add $3,%eax | |
| 15 | + add $3+1,%eax | |
| 16 | 16 | and $-4,%eax |
| 17 | 17 | jz p6 |
| 18 | 18 | |
| @@ -212,6 +212,7 @@ struct tree_node { · 211 unmodified lines | ||
| 212 | 212 | typedef struct alloca_list_struct { |
| 213 | 213 | size_t fp; |
| 214 | 214 | void *p; |
| 215 | + size_t size; | |
| 215 | 216 | struct alloca_list_struct *next; |
| 216 | 217 | } alloca_list_type; |
| 217 | 218 | |
| @@ -728,12 +729,22 @@ void __bound_new_region(void *p, size_t size) · 510 unmodified lines | ||
| 728 | 729 | last = NULL; |
| 729 | 730 | cur = alloca_list; |
| 730 | 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 | 743 | if (last) |
| 733 | 744 | last->next = cur->next; |
| 734 | 745 | else |
| 735 | 746 | alloca_list = cur->next; |
| 736 | − tree = splay_delete((size_t)p, tree); | |
| 747 | + tree = splay_delete((size_t)cur->p, tree); | |
| 737 | 748 | break; |
| 738 | 749 | } |
| 739 | 750 | last = cur; |
| @@ -743,6 +754,7 @@ void __bound_new_region(void *p, size_t size) · 3 unmodified lines | ||
| 743 | 754 | if (new) { |
| 744 | 755 | new->fp = fp; |
| 745 | 756 | new->p = p; |
| 757 | + new->size = size; | |
| 746 | 758 | new->next = alloca_list; |
| 747 | 759 | alloca_list = new; |
| 748 | 760 | } |
| @@ -1327,6 +1327,11 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) · 1326 unmodified lines | ||
| 1327 | 1327 | vpushv(vtop); |
| 1328 | 1328 | #endif |
| 1329 | 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 | 1335 | EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15 |
| 1331 | 1336 | EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16 |
| 1332 | 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 | 413 | pstrcat(buf, sizeof(buf), "/"); |
| 414 | 414 | put_stabs_r(s1, buf, N_SO, 0, 0, |
| 415 | 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 | 418 | text_section->data_offset, text_section, section_sym); |
| 418 | 419 | for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++) |
| 419 | 420 | put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0); |
| @@ -6100,6 +6101,9 @@ special_math_val: · 5680 unmodified lines | ||
| 6100 | 6101 | /* pass it as 'int' to avoid structure arg passing |
| 6101 | 6102 | problems */ |
| 6102 | 6103 | vseti(VT_LOCAL, loc); |
| 6104 | +#ifdef CONFIG_TCC_BCHECK | |
| 6105 | + loc -= tcc_state->do_bounds_check != 0; | |
| 6106 | +#endif | |
| 6103 | 6107 | ret.c = vtop->c; |
| 6104 | 6108 | if (ret_nregs < 0) |
| 6105 | 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 | 103 | 115_bound_setjmp.test: FLAGS += -b |
| 104 | 104 | 116_bound_setjmp2.test: FLAGS += -b |
| 105 | 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 | 109 | # Filter source directory in warnings/errors (out-of-tree builds) |
| 108 | 110 | FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' |