From 87a850f5537cccabc56d2f9b76faefe1454e4b19 Mon Sep 17 00:00:00 2001 From: jiang <30155751@qq.com> Date: Thu, 1 May 2014 15:15:01 +0800 Subject: [PATCH] fix its own making bug. Improved init_putz (). Modify the tests / Makefile to make the test more secure --- tcc.h | 2 ++ tccgen.c | 11 +++--- tests/Makefile | 10 ++++-- x86_64-gen.c | 97 +++++++++++++++++++++++++++----------------------- 4 files changed, 68 insertions(+), 52 deletions(-) diff --git a/tcc.h b/tcc.h index d9043637..e01643f1 100644 --- a/tcc.h +++ b/tcc.h @@ -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 diff --git a/tccgen.c b/tccgen.c index daf5f483..20011a0c 100644 --- a/tccgen.c +++ b/tccgen.c @@ -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 } } diff --git a/tests/Makefile b/tests/Makefile index a8b41f91..4c728eb6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -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 diff --git a/x86_64-gen.c b/x86_64-gen.c index f310815e..1f838e31 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -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, ®_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)