Checked on: - i386/x86_64 (linux/windows) - arm/arm64 (rapberry pi) - riscv64 (simulator) Not tested for arm softfloat because raspberry pi does not support it. Modifications: Makefile: add arm-asm.c to arm64_FILES add riscv64-asm.c (new file) to riscv64_FILES lib/Makefile: add fetch_and_add_arm.o(new file) to ARM_O add fetch_and_add_arm64.o(new file) to ARM64_O add fetch_and_add_riscv64.o(new file) to RISCV64_O add $(BCHECK_O) to OBJ-arm/OBJ-arm64/OBJ-riscv64 tcc.h: Enable CONFIG_TCC_BCHECK for arm32/arm64/riscv64 Add arm-asm.c, riscv64-asm.c tcctok.h: for arm use memmove4 instead of memcpy4 for arm use memmove8 instead of memcpy8 tccgen.c: put_extern_sym2: for arm check memcpy/memmove/memset/memmove4/memmove8 only use alloca for i386/x86_64 for arm use memmove4 instead of memcpy4 for arm use memmove8 instead of memcpy8 fix builtin_frame_address/builtin_return_address for arm/riscv64 tccrun.c: Add riscv64 support fix rt_getcontext/rt_get_caller_pc for arm tccelf.c: tcc_load_dll: Print filename for bad architecture libtcc.c: add arm-asm.c/riscv64-asm.c tcc-doc.texi: Add arm, arm64, riscv64 support for bound checking lib/bcheck.c: add __bound___aeabi_memcpy/__bound___aeabi_memmove __bound___aeabi_memmove4/__bound___aeabi_memmove8 __bound___aeabi_memset for arm call fetch_and_add_arm/fetch_and_add_arm64/fetch_and_add_riscv64 __bound_init: Fix type for start/end/ad __bound_malloc/__bound_memalign/__bound_realloc/__bound_calloc: Use size + 1 arm-gen.c: add bound checking code like i386/x86_64 assign_regs: only malloc if nb_args != 0 gen_opi/gen_opf: Fix reload problems arm-link.c: relocate_plt: Fix address calculating arm64-gen.c: add bound checking code like i386/x86_64 load/store: remove VT_BOUNDED from sv->r arm64_hfa_aux/arm64_hfa_aux: Fix array code gfunc_prolog: only malloc if n != 0 arm64-link.c: code_reloc/gotplt_entry_type/relocate: add R_AARCH64_LDST64_ABS_LO12_NC relocate: Use addXXle instead of writeXXle riscv64-gen.c: add bound checking code like i386/x86_64 add NB_ASM_REGS/CONFIG_TCC_ASM riscv64-link.c: relocate: Use addXXle instead of writeXXle i386-gen.c/x86_64-gen.c gen_bounds_epilog: Fix code (unrelated) tests/Makefile: add $(BTESTS) for arm/arm64/riscv64 tests/tests2/Makefile: Use 85 only on i386/x86_64 because of asm code Use 113 only on i386/x86_64 because of DLL code Add 112/114/115/116 for arm/arm64/riscv64 Fix FILTER (failed on riscv64) tests/boundtest.c: Only use alloca for i386/x86_64
297 lines
4.3 KiB
C
297 lines
4.3 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define NB_ITS 1000000
|
|
//#define NB_ITS 1
|
|
#define TAB_SIZE 100
|
|
|
|
int tab[TAB_SIZE];
|
|
int ret_sum;
|
|
char tab3[256];
|
|
|
|
int test1(void)
|
|
{
|
|
int i, sum = 0;
|
|
for(i=0;i<TAB_SIZE;i++) {
|
|
sum += tab[i];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
/* error */
|
|
int test2(void)
|
|
{
|
|
int i, sum = 0;
|
|
for(i=0;i<TAB_SIZE + 1;i++) {
|
|
sum += tab[i];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
/* actually, profiling test */
|
|
int test3(void)
|
|
{
|
|
int sum;
|
|
int i, it;
|
|
|
|
sum = 0;
|
|
for(it=0;it<NB_ITS;it++) {
|
|
for(i=0;i<TAB_SIZE;i++) {
|
|
sum += tab[i];
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
/* ok */
|
|
int test4(void)
|
|
{
|
|
int i, sum = 0;
|
|
int *tab4;
|
|
|
|
tab4 = malloc(20 * sizeof(int));
|
|
for(i=0;i<20;i++) {
|
|
sum += tab4[i];
|
|
}
|
|
free(tab4);
|
|
|
|
return sum;
|
|
}
|
|
|
|
/* error */
|
|
int test5(void)
|
|
{
|
|
int i, sum = 0;
|
|
int *tab4;
|
|
|
|
tab4 = malloc(20 * sizeof(int));
|
|
for(i=0;i<21;i++) {
|
|
sum += tab4[i];
|
|
}
|
|
free(tab4);
|
|
|
|
return sum;
|
|
}
|
|
|
|
/* error */
|
|
int test6(void)
|
|
{
|
|
int i, sum = 0;
|
|
int *tab4;
|
|
|
|
tab4 = malloc(20 * sizeof(int));
|
|
free(tab4);
|
|
for(i=0;i<21;i++) {
|
|
sum += tab4[i];
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
/* error */
|
|
int test7(void)
|
|
{
|
|
int i, sum = 0;
|
|
int *p;
|
|
|
|
for(i=0;i<TAB_SIZE + 1;i++) {
|
|
p = &tab[i];
|
|
if (i == TAB_SIZE)
|
|
printf("i=%d %x\n", i, p);
|
|
sum += *p;
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
/* ok */
|
|
int test8(void)
|
|
{
|
|
int i, sum = 0;
|
|
int tab[10];
|
|
|
|
for(i=0;i<10;i++) {
|
|
sum += tab[i];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
/* error */
|
|
int test9(void)
|
|
{
|
|
int i, sum = 0;
|
|
char tab[10];
|
|
|
|
for(i=0;i<11;i++) {
|
|
sum += tab[i];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
/* ok */
|
|
int test10(void)
|
|
{
|
|
char tab[10];
|
|
char tab1[10];
|
|
|
|
memset(tab, 0, 10);
|
|
memcpy(tab, tab1, 10);
|
|
memmove(tab, tab1, 10);
|
|
return 0;
|
|
}
|
|
|
|
/* error */
|
|
int test11(void)
|
|
{
|
|
char tab[10];
|
|
|
|
memset(tab, 0, 11);
|
|
return 0;
|
|
}
|
|
|
|
/* error */
|
|
int test12(void)
|
|
{
|
|
void *ptr;
|
|
ptr = malloc(10);
|
|
free(ptr);
|
|
free(ptr);
|
|
return 0;
|
|
}
|
|
|
|
/* error */
|
|
int test13(void)
|
|
{
|
|
char pad1 = 0;
|
|
char tab[10];
|
|
char pad2 = 0;
|
|
memset(tab, 'a', sizeof(tab));
|
|
return strlen(tab);
|
|
}
|
|
|
|
#if defined __i386__ || defined __x86_64__
|
|
#define allocf(x)
|
|
#else
|
|
#define alloca(x) malloc(x)
|
|
#define allocf(x) free(x)
|
|
#endif
|
|
|
|
int test14(void)
|
|
{
|
|
char *p = alloca(TAB_SIZE);
|
|
size_t ret;
|
|
memset(p, 'a', TAB_SIZE);
|
|
p[TAB_SIZE-1] = 0;
|
|
ret = strlen(p);
|
|
allocf(p);
|
|
return ret;
|
|
}
|
|
|
|
/* error */
|
|
int test15(void)
|
|
{
|
|
char *p = alloca(TAB_SIZE-1);
|
|
size_t ret;
|
|
memset(p, 'a', TAB_SIZE);
|
|
p[TAB_SIZE-1] = 0;
|
|
ret = strlen(p);
|
|
allocf(p);
|
|
return ret;
|
|
}
|
|
|
|
/* ok */
|
|
int test16()
|
|
{
|
|
char *demo = "This is only a test.";
|
|
char *p;
|
|
|
|
p = alloca(16);
|
|
strcpy(p,"12345678901234");
|
|
allocf(p);
|
|
|
|
/* Test alloca embedded in a larger expression */
|
|
printf("alloca : %s : %s\n", p, strcpy(alloca(strlen(demo)+1),demo) );
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* error */
|
|
int test17()
|
|
{
|
|
char *demo = "This is only a test.";
|
|
char *p;
|
|
|
|
p = alloca(16);
|
|
strcpy(p,"12345678901234");
|
|
allocf(p);
|
|
|
|
/* Test alloca embedded in a larger expression */
|
|
printf("alloca : %s : %s\n", p, strcpy(alloca(strlen(demo)),demo) );
|
|
|
|
return 0;
|
|
}
|
|
|
|
int (*table_test[])(void) = {
|
|
test1,
|
|
test2,
|
|
test3,
|
|
test4,
|
|
test5,
|
|
test6,
|
|
test7,
|
|
test8,
|
|
test9,
|
|
test10,
|
|
test11,
|
|
test12,
|
|
test13,
|
|
test14,
|
|
test15,
|
|
test16,
|
|
test17
|
|
};
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int i;
|
|
char *cp;
|
|
int index;
|
|
int (*ftest)(void);
|
|
int index_max = sizeof(table_test)/sizeof(table_test[0]);
|
|
|
|
/* check bounds checking main arg */
|
|
for (i = 0; i < argc; i++) {
|
|
cp = argv[i];
|
|
while (*cp) {
|
|
cp++;
|
|
}
|
|
}
|
|
|
|
if (argc < 2) {
|
|
printf(
|
|
"test TCC bound checking system\n"
|
|
"usage: boundtest N\n"
|
|
" 1 <= N <= %d\n", index_max);
|
|
exit(1);
|
|
}
|
|
|
|
index = 0;
|
|
if (argc >= 2)
|
|
index = atoi(argv[1]) - 1;
|
|
|
|
if ((index < 0) || (index >= index_max)) {
|
|
printf("N is outside of the valid range (%d)\n", index);
|
|
exit(2);
|
|
}
|
|
|
|
/* well, we also use bounds on this ! */
|
|
ftest = table_test[index];
|
|
ftest();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* without bound 0.77 s
|
|
* with bounds 4.73
|
|
*/
|