aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjiang <30155751@qq.com>2014-05-01 15:15:01 +0800
committerjiang <30155751@qq.com>2014-05-01 15:15:01 +0800
commit87a850f5537cccabc56d2f9b76faefe1454e4b19 (patch)
tree2f4078dc037e873d630b8e4d68518fe2697179a7
parent9e3713facd9d857201326ac2038ab6a8fb64a5fc (diff)
downloadtinycc-87a850f5537cccabc56d2f9b76faefe1454e4b19.tar.gz
tinycc-87a850f5537cccabc56d2f9b76faefe1454e4b19.tar.bz2
fix its own making bug. Improved init_putz (). Modify the tests / Makefile to make the test more secure
-rw-r--r--tcc.h2
-rw-r--r--tccgen.c9
-rw-r--r--tests/Makefile10
-rw-r--r--x86_64-gen.c97
4 files changed, 67 insertions, 51 deletions
diff --git a/tcc.h b/tcc.h
index d904363..e01643f 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 daf5f48..20011a0 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);
+ gfunc_call(3);
#else
- vpushi(0);
- vpushs(size);
+ vseti(VT_LOCAL, c);
+ gen_putz(vtop, size);
+ vtop--;
#endif
- gfunc_call(3);
}
}
diff --git a/tests/Makefile b/tests/Makefile
index a8b41f9..4c728eb 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 f310815..1f838e3 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, &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)