mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-14 07:10:07 +08:00
fix its own making bug. Improved init_putz (). Modify the tests / Makefile to make the test more secure
This commit is contained in:
parent
9e3713facd
commit
87a850f553
2
tcc.h
2
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
|
||||
|
11
tccgen.c
11
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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
97
x86_64-gen.c
97
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)
|
||||
|
Loading…
Reference in New Issue
Block a user