fix its own making bug. Improved init_putz (). Modify the tests / Makefile to make the test more secure

master
jiang 2014-05-01 15:15:01 +08:00
parent 9e3713facd
commit 87a850f553
4 changed files with 68 additions and 52 deletions

2
tcc.h
View File

@ -1338,6 +1338,8 @@ ST_FUNC void gen_le16(int c);
ST_FUNC void gen_le32(int c);
ST_FUNC void gen_addr32(int r, Sym *sym, int c);
ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
ST_FUNC void struct_copy(SValue *d, SValue *s, SValue *c);
ST_FUNC void gen_putz(SValue *d, int size);
#endif
#ifdef CONFIG_TCC_BCHECK

View File

@ -5224,16 +5224,17 @@ static void init_putz(CType *t, Section *sec, unsigned long c, int size)
if (sec) {
/* nothing to do because globals are already set to zero */
} else {
#ifdef TCC_TARGET_ARM
vpush_global_sym(&func_old_type, TOK_memset);
vseti(VT_LOCAL, c);
#ifdef TCC_TARGET_ARM
vpushs(size);
vpushi(0);
#else
vpushi(0);
vpushs(size);
#endif
gfunc_call(3);
#else
vseti(VT_LOCAL, c);
gen_putz(vtop, size);
vtop--;
#endif
}
}

View File

@ -70,7 +70,7 @@ ifdef LIBCRT
LIBCRT:=$(TOP)/$(LIBCRT)
endif
all test : $(TESTS)
all test : clean $(TESTS)
hello-exe: ../examples/ex1.c
@echo ------------ $@ ------------
@ -210,10 +210,14 @@ abitest-cc$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC)
abitest-tcc$(EXESUF): abitest.c libtcc.c
$(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE $(LIBS) $(LDFLAGS) -I$(top_srcdir)
abitest: abitest-cc$(EXESUF) abitest-tcc$(EXESUF)
abitest-tcc1$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC)
$(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS) -I$(top_srcdir)
abitest: abitest-cc$(EXESUF) abitest-tcc$(EXESUF) abitest-tcc1$(EXESUF)
@echo ------------ $@ ------------
./abitest-cc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
./abitest-tcc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
./abitest-tcc1$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
vla_test$(EXESUF): vla_test.c
$(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS)
@ -240,6 +244,6 @@ cache: tcc_g
clean:
$(MAKE) -C tests2 $@
rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc \
*-cc *-tcc *.exe \
*-cc *-tcc *.exe *-tcc1\
hello libtcc_test vla_test tcctest[1234] ex? tcc_g tcclib.h \
../lib/libcrt.a

View File

@ -592,6 +592,31 @@ static void gcall_or_jmp(int is_jmp)
}
}
void struct_copy(SValue *d, SValue *s, SValue *c)
{
if(!c->c.i)
return;
save_reg(TREG_RCX);
load(TREG_RCX, c);
load(TREG_RDI, d);
load(TREG_RSI, s);
o(0xa4f3);// rep movsb
}
void gen_putz(SValue *d, int size)
{
if(!size)
return;
save_reg(TREG_RAX);
o(0xb0);
g(0x00);
save_reg(TREG_RCX);
o(0xb8 + REG_VALUE(TREG_RCX)); /* mov $xx, r */
gen_le32(size);
load(TREG_RDI, d);
o(0xaaf3);//rep stos
}
#ifdef TCC_TARGET_PE
#define REGN 4
@ -1060,14 +1085,6 @@ static const uint8_t arg_regs[REGN] = {
TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9
};
static int arg_prepare_reg(int idx) {
if (idx == 2 || idx == 3)
/* idx=2: r10, idx=3: r11 */
return idx + 8;
else
return arg_regs[idx];
}
/* Generate function call. The function address is pushed first, then
all the parameters in call order. This functions pops all the
parameters and the function address. */
@ -1080,6 +1097,9 @@ void gfunc_call(int nb_args)
int nb_sse_args = 0;
int sse_reg, gen_reg;
/* fetch cpu flag before the following sub will change the value */
if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP)
gv(RC_INT);
/* calculate the number of integer/float register arguments */
for(i = 0; i < nb_args; i++) {
mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
@ -1276,7 +1296,7 @@ void gfunc_call(int nb_args)
}
/* XXX This should be superfluous. */
save_regs(0); /* save used temporary registers */
// save_regs(0); /* save used temporary registers */
/* then, we prepare register passing arguments.
Note that we cannot set RDX and RCX in this loop because gv()
@ -1289,36 +1309,34 @@ void gfunc_call(int nb_args)
/* Alter stack entry type so that gv() knows how to treat it */
vtop->type = type;
if (mode == x86_64_mode_sse) {
if (reg_count == 2) {
sse_reg -= 2;
gv(RC_FRET); /* Use pair load into xmm0 & xmm1 */
if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */
/* movaps %xmm0, %xmmN */
o(0x280f);
o(0xc0 + (sse_reg << 3));
/* movaps %xmm1, %xmmN */
o(0x280f);
o(0xc1 + ((sse_reg+1) << 3));
}
} else {
assert(reg_count == 1);
--sse_reg;
/* Load directly to register */
gv(RC_XMM0 << sse_reg);
}
sse_reg -= reg_count;
if (sse_reg + reg_count <= 8) {
if (reg_count == 2) {
ex_rc = RC_XMM0 << (sse_reg + 1);
gv(RC_XMM0 << sse_reg);
}else{
assert(reg_count == 1);
/* Load directly to register */
gv(RC_XMM0 << sse_reg);
}
}
} else if (mode == x86_64_mode_integer) {
/* simple type */
/* XXX: implicit cast ? */
int d;
gen_reg -= reg_count;
r = gv(RC_INT);
int d = arg_prepare_reg(gen_reg);
orex(1,d,r,0x89); /* mov */
o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
if (reg_count == 2) {
d = arg_prepare_reg(gen_reg+1);
orex(1,d,vtop->r2,0x89); /* mov */
o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));
}
if (gen_reg + reg_count <= REGN) {
if (reg_count == 2) {
d = arg_regs[gen_reg+1];
ex_rc = reg_classes[d] & ~RC_MASK;
d = arg_regs[gen_reg];
gv(reg_classes[d] & ~RC_MASK);
}else{
assert(reg_count == 1);
d = arg_regs[gen_reg];
gv(reg_classes[d] & ~RC_MASK);
}
}
}
vtop--;
}
@ -1330,15 +1348,6 @@ void gfunc_call(int nb_args)
(or edx/ecx) currently, which the below writes would clobber.
So evict all remaining operands here. */
save_regs(0);
/* Copy R10 and R11 into RDX and RCX, respectively */
if (nb_reg_args > 2) {
o(0xd2894c); /* mov %r10, %rdx */
if (nb_reg_args > 3) {
o(0xd9894c); /* mov %r11, %rcx */
}
}
oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
gcall_or_jmp(0);
if (args_size)