History

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

jiang committed 12 years ago

Commit 87a850f1 parent 9e3713f4 files · +67 −51Browse files

Unified · Split

4 files
  1. tcc.h +2 −0
  2. tccgen.c +5 −4
  3. tests/Makefile +7 −3
  4. x86_64-gen.c +53 −44
tcc.h+2−0
@@ -1338,6 +1338,8 @@ ST_FUNC void gen_le16(int c); · 1337 unmodified lines
13381338 ST_FUNC void gen_le32(int c);
13391339 ST_FUNC void gen_addr32(int r, Sym *sym, int c);
13401340 ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
1341+ST_FUNC void struct_copy(SValue *d, SValue *s, SValue *c);
1342+ST_FUNC void gen_putz(SValue *d, int size);
13411343 #endif
13421344
13431345 #ifdef CONFIG_TCC_BCHECK
tccgen.c+5−4
@@ -5224,16 +5224,17 @@ static void init_putz(CType *t, Section *sec, unsigned long c, int size) · 5223 unmodified lines
52245224 if (sec) {
52255225 /* nothing to do because globals are already set to zero */
52265226 } else {
5227+#ifdef TCC_TARGET_ARM
52275228 vpush_global_sym(&func_old_type, TOK_memset);
52285229 vseti(VT_LOCAL, c);
5229−#ifdef TCC_TARGET_ARM
52305230 vpushs(size);
52315231 vpushi(0);
5232+ gfunc_call(3);
52325233 #else
5233− vpushi(0);
5234− vpushs(size);
5234+ vseti(VT_LOCAL, c);
5235+ gen_putz(vtop, size);
5236+ vtop--;
52355237 #endif
5236− gfunc_call(3);
52375238 }
52385239 }
52395240
tests/Makefile+7−3
@@ -70,7 +70,7 @@ ifdef LIBCRT · 69 unmodified lines
7070 LIBCRT:=$(TOP)/$(LIBCRT)
7171 endif
7272
73−all test : $(TESTS)
73+all test : clean $(TESTS)
7474
7575 hello-exe: ../examples/ex1.c
7676 @echo ------------ $@ ------------
@@ -210,10 +210,14 @@ abitest-cc$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC) · 133 unmodified lines
210210 abitest-tcc$(EXESUF): abitest.c libtcc.c
211211 $(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE $(LIBS) $(LDFLAGS) -I$(top_srcdir)
212212
213−abitest: abitest-cc$(EXESUF) abitest-tcc$(EXESUF)
213+abitest-tcc1$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC)
214+ $(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS) -I$(top_srcdir)
215+
216+abitest: abitest-cc$(EXESUF) abitest-tcc$(EXESUF) abitest-tcc1$(EXESUF)
214217 @echo ------------ $@ ------------
215218 ./abitest-cc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
216219 ./abitest-tcc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
220+ ./abitest-tcc1$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
217221
218222 vla_test$(EXESUF): vla_test.c
219223 $(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS)
@@ -240,6 +244,6 @@ cache: tcc_g · 20 unmodified lines
240244 clean:
241245 $(MAKE) -C tests2 $@
242246 rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc \
243− *-cc *-tcc *.exe \
247+ *-cc *-tcc *.exe *-tcc1\
244248 hello libtcc_test vla_test tcctest[1234] ex? tcc_g tcclib.h \
245249 ../lib/libcrt.a
x86_64-gen.c+53−44
@@ -592,6 +592,31 @@ static void gcall_or_jmp(int is_jmp) · 591 unmodified lines
592592 }
593593 }
594594
595+void struct_copy(SValue *d, SValue *s, SValue *c)
596+{
597+ if(!c->c.i)
598+ return;
599+ save_reg(TREG_RCX);
600+ load(TREG_RCX, c);
601+ load(TREG_RDI, d);
602+ load(TREG_RSI, s);
603+ o(0xa4f3);// rep movsb
604+}
605+
606+void gen_putz(SValue *d, int size)
607+{
608+ if(!size)
609+ return;
610+ save_reg(TREG_RAX);
611+ o(0xb0);
612+ g(0x00);
613+ save_reg(TREG_RCX);
614+ o(0xb8 + REG_VALUE(TREG_RCX)); /* mov $xx, r */
615+ gen_le32(size);
616+ load(TREG_RDI, d);
617+ o(0xaaf3);//rep stos
618+}
619+
595620 #ifdef TCC_TARGET_PE
596621
597622 #define REGN 4
@@ -1060,14 +1085,6 @@ static const uint8_t arg_regs[REGN] = { · 462 unmodified lines
10601085 TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9
10611086 };
10621087
1063−static int arg_prepare_reg(int idx) {
1064− if (idx == 2 || idx == 3)
1065− /* idx=2: r10, idx=3: r11 */
1066− return idx + 8;
1067− else
1068− return arg_regs[idx];
1069−}
1070−
10711088 /* Generate function call. The function address is pushed first, then
10721089 all the parameters in call order. This functions pops all the
10731090 parameters and the function address. */
@@ -1080,6 +1097,9 @@ void gfunc_call(int nb_args) · 6 unmodified lines
10801097 int nb_sse_args = 0;
10811098 int sse_reg, gen_reg;
10821099
1100+ /* fetch cpu flag before the following sub will change the value */
1101+ if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP)
1102+ gv(RC_INT);
10831103 /* calculate the number of integer/float register arguments */
10841104 for(i = 0; i < nb_args; i++) {
10851105 mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
@@ -1276,7 +1296,7 @@ void gfunc_call(int nb_args) · 190 unmodified lines
12761296 }
12771297
12781298 /* XXX This should be superfluous. */
1279− save_regs(0); /* save used temporary registers */
1299+ // save_regs(0); /* save used temporary registers */
12801300
12811301 /* then, we prepare register passing arguments.
12821302 Note that we cannot set RDX and RCX in this loop because gv()
@@ -1289,36 +1309,34 @@ void gfunc_call(int nb_args) · 6 unmodified lines
12891309 /* Alter stack entry type so that gv() knows how to treat it */
12901310 vtop->type = type;
12911311 if (mode == x86_64_mode_sse) {
1292− if (reg_count == 2) {
1293− sse_reg -= 2;
1294− gv(RC_FRET); /* Use pair load into xmm0 & xmm1 */
1295− if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */
1296− /* movaps %xmm0, %xmmN */
1297− o(0x280f);
1298− o(0xc0 + (sse_reg << 3));
1299− /* movaps %xmm1, %xmmN */
1300− o(0x280f);
1301− o(0xc1 + ((sse_reg+1) << 3));
1302− }
1303− } else {
1304− assert(reg_count == 1);
1305− --sse_reg;
1306− /* Load directly to register */
1307− gv(RC_XMM0 << sse_reg);
1308− }
1312+ sse_reg -= reg_count;
1313+ if (sse_reg + reg_count <= 8) {
1314+ if (reg_count == 2) {
1315+ ex_rc = RC_XMM0 << (sse_reg + 1);
1316+ gv(RC_XMM0 << sse_reg);
1317+ }else{
1318+ assert(reg_count == 1);
1319+ /* Load directly to register */
1320+ gv(RC_XMM0 << sse_reg);
1321+ }
1322+ }
13091323 } else if (mode == x86_64_mode_integer) {
13101324 /* simple type */
13111325 /* XXX: implicit cast ? */
1326+ int d;
13121327 gen_reg -= reg_count;
1313− r = gv(RC_INT);
1314− int d = arg_prepare_reg(gen_reg);
1315− orex(1,d,r,0x89); /* mov */
1316− o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
1317− if (reg_count == 2) {
1318− d = arg_prepare_reg(gen_reg+1);
1319− orex(1,d,vtop->r2,0x89); /* mov */
1320− o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));
1321− }
1328+ if (gen_reg + reg_count <= REGN) {
1329+ if (reg_count == 2) {
1330+ d = arg_regs[gen_reg+1];
1331+ ex_rc = reg_classes[d] & ~RC_MASK;
1332+ d = arg_regs[gen_reg];
1333+ gv(reg_classes[d] & ~RC_MASK);
1334+ }else{
1335+ assert(reg_count == 1);
1336+ d = arg_regs[gen_reg];
1337+ gv(reg_classes[d] & ~RC_MASK);
1338+ }
1339+ }
13221340 }
13231341 vtop--;
13241342 }
@@ -1330,15 +1348,6 @@ void gfunc_call(int nb_args) · 5 unmodified lines
13301348 (or edx/ecx) currently, which the below writes would clobber.
13311349 So evict all remaining operands here. */
13321350 save_regs(0);
1333−
1334− /* Copy R10 and R11 into RDX and RCX, respectively */
1335− if (nb_reg_args > 2) {
1336− o(0xd2894c); /* mov %r10, %rdx */
1337− if (nb_reg_args > 3) {
1338− o(0xd9894c); /* mov %r11, %rcx */
1339− }
1340− }
1341−
13421351 oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
13431352 gcall_or_jmp(0);
13441353 if (args_size)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t