x86-64: chkstk, alloca

This commit is contained in:
grischka 2009-07-18 22:06:54 +02:00
parent c0fc0fa0c4
commit fc977d56c9
8 changed files with 104 additions and 59 deletions

View File

@ -11,6 +11,9 @@ LIBS_P=
ifneq ($(GCC_MAJOR),2)
CFLAGS+=-fno-strict-aliasing
ifneq ($(GCC_MAJOR),3)
CFLAGS+=-Wno-pointer-sign -Wno-sign-compare -D_FORTIFY_SOURCE=0
endif
endif
ifeq ($(ARCH),i386)
@ -19,15 +22,8 @@ ifeq ($(GCC_MAJOR),2)
CFLAGS+=-m386 -malign-functions=0
else
CFLAGS+=-march=i386 -falign-functions=0
ifneq ($(GCC_MAJOR),3)
CFLAGS+=-Wno-pointer-sign -Wno-sign-compare -D_FORTIFY_SOURCE=0
endif
endif
endif
ifeq ($(ARCH),x86-64)
CFLAGS+=-Wno-pointer-sign
endif
ifndef CONFIG_WIN32
LIBS=-lm
@ -36,26 +32,29 @@ LIBS+=-ldl
endif
endif
ifdef CONFIG_WIN32
NATIVE_TARGET=-DTCC_TARGET_PE
LIBTCC1=libtcc1.a
else
ifeq ($(ARCH),i386)
NATIVE_TARGET=-DTCC_TARGET_I386
LIBTCC1=libtcc1.a
BCHECK_O=bcheck.o
else
ifeq ($(ARCH),arm)
NATIVE_TARGET=-DTCC_TARGET_ARM
NATIVE_TARGET+=$(if $(wildcard /lib/ld-linux.so.3),-DTCC_ARM_EABI)
NATIVE_TARGET+=$(if $(shell grep -l "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo),-DTCC_ARM_VFP)
ALLOCA_O=alloca86.o alloca86-bt.o
else
ifeq ($(ARCH),x86-64)
NATIVE_TARGET=-DTCC_TARGET_X86_64
LIBTCC1=libtcc1.a
BCHECK_O=
ALLOCA_O=alloca86_64.o
endif
endif
ifeq ($(ARCH),arm)
NATIVE_TARGET=-DTCC_TARGET_ARM
NATIVE_TARGET+=$(if $(wildcard /lib/ld-linux.so.3),-DTCC_ARM_EABI)
NATIVE_TARGET+=$(if $(shell grep -l "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo),-DTCC_ARM_VFP)
endif
ifdef CONFIG_WIN32
NATIVE_TARGET+=-DTCC_TARGET_PE
BCHECK_O=
endif
ifneq ($(wildcard /lib/ld-uClibc.so.0),)
@ -70,7 +69,6 @@ endif
ifeq ($(TOP),.)
PROGS=tcc$(EXESUF)
I386_CROSS = i386-tcc$(EXESUF)
WIN32_CROSS = i386-win32-tcc$(EXESUF)
WIN64_CROSS = x86_64-win32-tcc$(EXESUF)
@ -171,26 +169,19 @@ tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
$(CC) -o $@ $< $(CFLAGS)
# TinyCC runtime libraries
LIBTCC1_OBJS=libtcc1.o
LIBTCC1_OBJS=libtcc1.o $(ALLOCA_O)
LIBTCC1_CC=$(CC)
VPATH+=lib
ifdef CONFIG_WIN32
# for windows, we must use TCC because we generate ELF objects
LIBTCC1_OBJS+=crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
LIBTCC1_CC=./tcc.exe -Bwin32 -Iinclude $(NATIVE_TARGET)
VPATH+=win32/lib
endif
ifeq ($(ARCH),i386)
LIBTCC1_OBJS+=alloca86.o alloca86-bt.o
else
ifeq ($(ARCH),x86-64)
LIBTCC1_OBJS+=alloca86_64.o
endif
endif
%.o: %.c
$(LIBTCC1_CC) -o $@ -c $< -O2 -Wall
%.o: %.S
$(LIBTCC1_CC) -o $@ -c $<

View File

@ -1,5 +1,5 @@
/* ---------------------------------------------- */
/* alloca86b.S */
/* alloca86-bt.S */
#include "../config.h"

View File

@ -7,13 +7,16 @@
alloca:
pop %rdx
#ifdef TCC_TARGET_PE
mov %rcx,%rax
#else
mov %rdi,%rax
#endif
add $15,%rax
and $-16,%rax
jz p3
#ifdef TCC_TARGET_PE
/* XXX: not tested */
p1:
cmp $4096,%rax
jle p2
@ -26,6 +29,10 @@ p2:
sub %rax,%rsp
mov %rsp,%rax
#ifdef TCC_TARGET_PE
add $32,%rax
#endif
p3:
push %rdx
ret

View File

@ -193,8 +193,8 @@ typedef struct _IMAGE_EXPORT_DIRECTORY {
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk;
DWORD Characteristics;
DWORD OriginalFirstThunk;
};
DWORD TimeDateStamp;
DWORD ForwarderChain;
@ -350,12 +350,7 @@ ST_DATA struct pe_header pe_header = {
0x0002, /*WORD Subsystem; */
0x0000, /*WORD DllCharacteristics; */
0x00100000, /*DWORD SizeOfStackReserve; */
#ifdef TCC_TARGET_X86_64
// need to have a __chkstk eventually
0x00008000, /*DWORD SizeOfStackCommit; */
#else
0x00001000, /*DWORD SizeOfStackCommit; */
#endif
0x00100000, /*DWORD SizeOfHeapReserve; */
0x00001000, /*DWORD SizeOfHeapCommit; */
0x00000000, /*DWORD LoaderFlags; */

View File

@ -81,8 +81,8 @@ test4: test.ref
@if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
# memory and bound check auto test
BOUNDS_OK = 1 4 8 10
BOUNDS_FAIL= 2 5 7 9 11 12 13
BOUNDS_OK = 1 4 8 10 14
BOUNDS_FAIL= 2 5 7 9 11 12 13 15
btest: boundtest.c
@echo ------------ $@ ------------

View File

@ -169,6 +169,23 @@ int test13(void)
return strlen(tab);
}
int test14(void)
{
char *p = alloca(TAB_SIZE);
memset(p, 'a', TAB_SIZE);
p[TAB_SIZE-1] = 0;
return strlen(p);
}
/* error */
int test15(void)
{
char *p = alloca(TAB_SIZE-1);
memset(p, 'a', TAB_SIZE);
p[TAB_SIZE-1] = 0;
return strlen(p);
}
int (*table_test[])(void) = {
test1,
test1,
@ -184,6 +201,8 @@ int (*table_test[])(void) = {
test11,
test12,
test13,
test14,
test15,
};
int main(int argc, char **argv)

View File

@ -1,29 +1,61 @@
// =================================================
// chkstk.s
/* ---------------------------------------------- */
/* chkstk86.s */
#include "../../config.h"
/* ---------------------------------------------- */
#ifndef TCC_TARGET_X86_64
/* ---------------------------------------------- */
.text
.globl __chkstk
__chkstk:
xchg (%esp), %ebp // store ebp, get ret.addr
push %ebp // push ret.addr
lea 4(%esp), %ebp // setup frame ptr
push %ecx // save ecx
mov %ebp, %ecx
xchg (%esp),%ebp /* store ebp, get ret.addr */
push %ebp /* push ret.addr */
lea 4(%esp),%ebp /* setup frame ptr */
push %ecx /* save ecx */
mov %ebp,%ecx
P0:
sub $4096,%ecx
test %eax,(%ecx)
sub $4096,%eax
cmp $4096,%eax
jge P0
sub $4096,%ecx
test %eax,(%ecx)
sub $4096,%eax
cmp $4096,%eax
jge P0
sub %eax,%ecx
test %eax,(%ecx)
sub %eax,%ecx
mov %esp,%eax
test %eax,(%ecx)
mov %ecx,%esp
mov %esp,%eax
mov %ecx,%esp
mov (%eax),%ecx /* restore ecx */
jmp *4(%eax)
mov (%eax),%ecx // restore ecx
mov 4(%eax),%eax
push %eax
ret
/* ---------------------------------------------- */
#else
/* ---------------------------------------------- */
.globl __chkstk
__chkstk:
xchg (%rsp),%rbp /* store ebp, get ret.addr */
push %rbp /* push ret.addr */
lea 8(%rsp),%rbp /* setup frame ptr */
push %rcx /* save ecx */
mov %rbp,%rcx
movslq %eax,%rax
P0:
sub $4096,%rcx
test %rax,(%rcx)
sub $4096,%rax
cmp $4096,%rax
jge P0
sub %rax,%rcx
test %rax,(%rcx)
mov %rsp,%rax
mov %rcx,%rsp
mov (%rax),%rcx /* restore ecx */
jmp *8(%rax)
/* ---------------------------------------------- */
#endif
/* ---------------------------------------------- */

View File

@ -919,12 +919,13 @@ void gfunc_epilog(void)
v = (-loc + 15) & -16;
saved_ind = ind;
ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
#if 0 // def TCC_TARGET_PE - don't have __chkstk yet, because assembler does not work
#ifdef TCC_TARGET_PE
if (v >= 4096) {
Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
oad(0xb8, v); /* mov stacksize, %eax */
oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
greloc(cur_text_section, sym, ind-4, R_X86_64_PC32);
o(0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */
} else
#endif
{