Bound checking fixes
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
This commit is contained in:
parent
352e1d0fc4
commit
afc0917f88
11 changed files with 104 additions and 4 deletions
|
@ -2255,6 +2255,10 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) {
|
||||||
vpushv(vtop);
|
vpushv(vtop);
|
||||||
#endif
|
#endif
|
||||||
r = intr(gv(RC_INT));
|
r = intr(gv(RC_INT));
|
||||||
|
#if defined(CONFIG_TCC_BCHECK)
|
||||||
|
if (tcc_state->do_bounds_check)
|
||||||
|
o(0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */
|
||||||
|
#endif
|
||||||
o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
|
o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
|
||||||
#ifdef TCC_ARM_EABI
|
#ifdef TCC_ARM_EABI
|
||||||
if (align < 8)
|
if (align < 8)
|
||||||
|
|
|
@ -2046,6 +2046,11 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) {
|
||||||
vpushv(vtop);
|
vpushv(vtop);
|
||||||
#endif
|
#endif
|
||||||
r = intr(gv(RC_INT));
|
r = intr(gv(RC_INT));
|
||||||
|
#if defined(CONFIG_TCC_BCHECK)
|
||||||
|
if (tcc_state->do_bounds_check)
|
||||||
|
o(0x91004000 | r | r << 5); // add x(r),x(r),#15+1
|
||||||
|
else
|
||||||
|
#endif
|
||||||
o(0x91003c00 | r | r << 5); // add x(r),x(r),#15
|
o(0x91003c00 | r | r << 5); // add x(r),x(r),#15
|
||||||
o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15
|
o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15
|
||||||
o(0xcb2063ff | r << 16); // sub sp,sp,x(r)
|
o(0xcb2063ff | r << 16); // sub sp,sp,x(r)
|
||||||
|
|
|
@ -12,7 +12,7 @@ _(__bound_alloca):
|
||||||
pop %edx
|
pop %edx
|
||||||
pop %eax
|
pop %eax
|
||||||
mov %eax, %ecx
|
mov %eax, %ecx
|
||||||
add $3,%eax
|
add $3+1,%eax
|
||||||
and $-4,%eax
|
and $-4,%eax
|
||||||
jz p6
|
jz p6
|
||||||
|
|
||||||
|
|
16
lib/bcheck.c
16
lib/bcheck.c
|
@ -212,6 +212,7 @@ struct tree_node {
|
||||||
typedef struct alloca_list_struct {
|
typedef struct alloca_list_struct {
|
||||||
size_t fp;
|
size_t fp;
|
||||||
void *p;
|
void *p;
|
||||||
|
size_t size;
|
||||||
struct alloca_list_struct *next;
|
struct alloca_list_struct *next;
|
||||||
} alloca_list_type;
|
} alloca_list_type;
|
||||||
|
|
||||||
|
@ -728,12 +729,22 @@ void __bound_new_region(void *p, size_t size)
|
||||||
last = NULL;
|
last = NULL;
|
||||||
cur = alloca_list;
|
cur = alloca_list;
|
||||||
while (cur) {
|
while (cur) {
|
||||||
if (cur->fp == fp && cur->p == p) {
|
#if defined(__i386__) || (defined(__arm__) && !defined(TCC_ARM_EABI))
|
||||||
|
int align = 4;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
int align = 8;
|
||||||
|
#else
|
||||||
|
int align = 16;
|
||||||
|
#endif
|
||||||
|
void *cure = (void *)((char *)cur->p + ((cur->size + align) & -align));
|
||||||
|
void *pe = (void *)((char *)p + ((size + align) & -align));
|
||||||
|
if (cur->fp == fp && ((cur->p <= p && cure > p) ||
|
||||||
|
(p <= cur->p && pe > cur->p))) {
|
||||||
if (last)
|
if (last)
|
||||||
last->next = cur->next;
|
last->next = cur->next;
|
||||||
else
|
else
|
||||||
alloca_list = cur->next;
|
alloca_list = cur->next;
|
||||||
tree = splay_delete((size_t)p, tree);
|
tree = splay_delete((size_t)cur->p, tree);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
last = cur;
|
last = cur;
|
||||||
|
@ -743,6 +754,7 @@ void __bound_new_region(void *p, size_t size)
|
||||||
if (new) {
|
if (new) {
|
||||||
new->fp = fp;
|
new->fp = fp;
|
||||||
new->p = p;
|
new->p = p;
|
||||||
|
new->size = size;
|
||||||
new->next = alloca_list;
|
new->next = alloca_list;
|
||||||
alloca_list = new;
|
alloca_list = new;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1327,6 +1327,11 @@ ST_FUNC void gen_vla_alloc(CType *type, int align)
|
||||||
vpushv(vtop);
|
vpushv(vtop);
|
||||||
#endif
|
#endif
|
||||||
rr = ireg(gv(RC_INT));
|
rr = ireg(gv(RC_INT));
|
||||||
|
#if defined(CONFIG_TCC_BCHECK)
|
||||||
|
if (tcc_state->do_bounds_check)
|
||||||
|
EI(0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+1
|
||||||
|
else
|
||||||
|
#endif
|
||||||
EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15
|
EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15
|
||||||
EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16
|
EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16
|
||||||
ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr
|
ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr
|
||||||
|
|
6
tccgen.c
6
tccgen.c
|
@ -413,7 +413,8 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
|
||||||
pstrcat(buf, sizeof(buf), "/");
|
pstrcat(buf, sizeof(buf), "/");
|
||||||
put_stabs_r(s1, buf, N_SO, 0, 0,
|
put_stabs_r(s1, buf, N_SO, 0, 0,
|
||||||
text_section->data_offset, text_section, section_sym);
|
text_section->data_offset, text_section, section_sym);
|
||||||
put_stabs_r(s1, file->prev->filename, N_SO, 0, 0,
|
put_stabs_r(s1, file->prev ? file->prev->filename : file->filename,
|
||||||
|
N_SO, 0, 0,
|
||||||
text_section->data_offset, text_section, section_sym);
|
text_section->data_offset, text_section, section_sym);
|
||||||
for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++)
|
for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++)
|
||||||
put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
|
put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
|
||||||
|
@ -6100,6 +6101,9 @@ special_math_val:
|
||||||
/* pass it as 'int' to avoid structure arg passing
|
/* pass it as 'int' to avoid structure arg passing
|
||||||
problems */
|
problems */
|
||||||
vseti(VT_LOCAL, loc);
|
vseti(VT_LOCAL, loc);
|
||||||
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
|
loc -= tcc_state->do_bounds_check != 0;
|
||||||
|
#endif
|
||||||
ret.c = vtop->c;
|
ret.c = vtop->c;
|
||||||
if (ret_nregs < 0)
|
if (ret_nregs < 0)
|
||||||
vtop--;
|
vtop--;
|
||||||
|
|
35
tests/tests2/121_struct_return.c
Normal file
35
tests/tests2/121_struct_return.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int data[4];
|
||||||
|
double d1;
|
||||||
|
double d2;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
Node init(Node self) {
|
||||||
|
self.data[0] = 0;
|
||||||
|
self.data[1] = 1;
|
||||||
|
self.data[2] = 2;
|
||||||
|
self.data[3] = 3;
|
||||||
|
self.d1 = 1234;
|
||||||
|
self.d2 = 2345;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy(Node self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_data(Node data) {
|
||||||
|
printf ("%d %d %d %d %g %g\n",
|
||||||
|
data.data[0], data.data[1], data.data[2], data.data[3],
|
||||||
|
data.d1, data.d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
/* This code resulted in a bounds checking error */
|
||||||
|
Node data;
|
||||||
|
dummy (data);
|
||||||
|
char val;
|
||||||
|
data = init (data);
|
||||||
|
print_data(data);
|
||||||
|
}
|
1
tests/tests2/121_struct_return.expect
Normal file
1
tests/tests2/121_struct_return.expect
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0 1 2 3 1234 2345
|
31
tests/tests2/122_vla_reuse.c
Normal file
31
tests/tests2/122_vla_reuse.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
int first=1;
|
||||||
|
int *p[101];
|
||||||
|
if (0) {
|
||||||
|
lab:;
|
||||||
|
}
|
||||||
|
int x[n % 100 + 1];
|
||||||
|
if (first == 0) {
|
||||||
|
if (&x[0] != p[n % 100 + 1]) {
|
||||||
|
printf ("ERROR: %d %p $p\n", &x[0], p[n % 100 + 1]);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p[n % 100 + 1] = &x[0];
|
||||||
|
first = n < 100;
|
||||||
|
}
|
||||||
|
x[0] = 1;
|
||||||
|
x[n % 100] = 2;
|
||||||
|
n++;
|
||||||
|
if (n < 100000)
|
||||||
|
goto lab;
|
||||||
|
printf ("OK\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
1
tests/tests2/122_vla_reuse.expect
Normal file
1
tests/tests2/122_vla_reuse.expect
Normal file
|
@ -0,0 +1 @@
|
||||||
|
OK
|
|
@ -103,6 +103,8 @@ GEN-ALWAYS =
|
||||||
115_bound_setjmp.test: FLAGS += -b
|
115_bound_setjmp.test: FLAGS += -b
|
||||||
116_bound_setjmp2.test: FLAGS += -b
|
116_bound_setjmp2.test: FLAGS += -b
|
||||||
117_builtins.test: T1 = ( $(TCC) -run $1 && $(TCC) -b -run $1 )
|
117_builtins.test: T1 = ( $(TCC) -run $1 && $(TCC) -b -run $1 )
|
||||||
|
121_struct_return.test: FLAGS += -b
|
||||||
|
122_vla_reuse.test: FLAGS += -b
|
||||||
|
|
||||||
# Filter source directory in warnings/errors (out-of-tree builds)
|
# Filter source directory in warnings/errors (out-of-tree builds)
|
||||||
FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'
|
FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'
|
||||||
|
|
Loading…
Reference in a new issue