aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrischka <grischka>2017-10-11 18:13:43 +0200
committergrischka <grischka>2017-10-11 18:13:43 +0200
commitda8c62f75d893449e232944fc62566c020b4d010 (patch)
tree977fec8d53d90ceb8c718f07f47c2bc9cbd6edfc
parentfaa9744f5d13c94c7298bf08e8d1eedca5db88a9 (diff)
downloadtinycc-da8c62f75d893449e232944fc62566c020b4d010.tar.gz
tinycc-da8c62f75d893449e232944fc62566c020b4d010.tar.bz2
various stuff
win32/Makefile ("for cygwin") removed - On cygwin, the normal ./configure && make can be used with either cygwin's "GCC for Win32 Toolchain" ./configure --cross-prefix=i686-w64-mingw32- or with an existing tcc: ./configure --cc=<old-tccdir>/tcc.exe tcctest.c: - exclude test_high_clobbers() on _WIN64 (does not work) tests2/95_bitfield.c: - use 'signed char' for ARM (where default 'char' is unsigned) tests: - remove -I "expr" diff option to allow tests with busybox-diff. libtcc.c, tcc.c: - removed -iwithprefix option. It is supposed to be combined with -iprefix which we don't have either. tccgen.c: - fix assignments and return of 'void', as in void f() { void *p, *q; *p = *q: return *p; } This appears to be allowed but should do nothing. tcc.h, libtcc.c, tccpp.c: - Revert "Introduce VIP sysinclude paths which are always searched first" This reverts commit 1d5e386b0a78393ac6b670c209a185849ec798a1. The patch was giving tcc's system includes priority over -I which is not how it should be. tccelf.c: - add DT_TEXTREL tag only if text relocations are actually used (which is likely not the case on x86_64) - prepare_dynamic_rel(): avoid relocation of unresolved (weak) symbols tccrun.c: - for HAVE_SELINUX, use two mappings to the same (real) file. (it was so once except the RX mapping wasn't used at all). tccpe.c: - fix relocation constant used for x86_64 (by Andrei E. Warentin) - #ifndef _WIN32 do "chmod 755 ..." to get runnable exes on cygwin. tccasm.c: - keep forward asm labels static, otherwise they will endup in dynsym eventually. configure, Makefile: - mingw32: respect ./configure options --bindir --docdir --libdir - allow overriding tcc when building libtcc1.a and libtcc.def with make XTCC=<tcc program to use> - use $(wildcard ...) for install to allow installing just a cross compiler for example make cross-arm make install - use name <target>-libtcc1.a build-tcc.bat: - add options: -clean, -b bindir
-rw-r--r--Makefile111
-rwxr-xr-xconfigure68
-rw-r--r--include/stdarg.h5
-rw-r--r--lib/Makefile14
-rw-r--r--libtcc.c39
-rw-r--r--libtcc.h3
-rw-r--r--tcc.c5
-rw-r--r--tcc.h31
-rw-r--r--tccasm.c2
-rw-r--r--tccelf.c210
-rw-r--r--tccgen.c38
-rw-r--r--tccpe.c35
-rw-r--r--tccpp.c49
-rw-r--r--tccrun.c53
-rw-r--r--tcctok.h16
-rw-r--r--tests/Makefile4
-rw-r--r--tests/pp/13.expect1
-rw-r--r--tests/pp/15.c4
-rw-r--r--tests/pp/15.expect2
-rw-r--r--tests/pp/Makefile4
-rw-r--r--tests/tcctest.c7
-rw-r--r--tests/tests2/95_bitfields.c2
-rw-r--r--tests/tests2/96_nodata_wanted.c2
-rw-r--r--tests/tests2/96_nodata_wanted.expect2
-rw-r--r--tests/tests2/Makefile2
-rw-r--r--win32/Makefile148
-rw-r--r--win32/build-tcc.bat105
-rw-r--r--win32/lib/crt1.c21
-rw-r--r--win32/lib/wincrt1.c76
-rw-r--r--win32/tcc-win32.txt19
30 files changed, 424 insertions, 654 deletions
diff --git a/Makefile b/Makefile
index 3a5c000..8888149 100644
--- a/Makefile
+++ b/Makefile
@@ -98,16 +98,17 @@ TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67
LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince
PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
-LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),libtcc1-$X.a)
+LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)
# build cross compilers & libs
cross: $(LIBTCC1_CROSS) $(PROGS_CROSS)
# build specific cross compiler & lib
-cross-%: %-tcc$(EXESUF) libtcc1-%.a ;
+cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
-install: install$(CFGWIN)
-uninstall: uninstall$(CFGWIN)
+install: ; @$(MAKE) --no-print-directory install$(CFGWIN)
+install-strip: ; @$(MAKE) --no-print-directory install$(CFGWIN) CONFIG_strip=yes
+uninstall: ; @$(MAKE) --no-print-directory uninstall$(CFGWIN)
ifdef CONFIG_cross
all : cross
@@ -143,10 +144,10 @@ DEFINES += $(DEF-$(or $(findstring win,$T),unx))
ifneq ($(X),)
ifeq ($(CONFIG_WIN32),yes)
-DEF-win += -DTCC_LIBTCC1="\"libtcc1-$T.a\""
-DEF-unx += -DTCC_LIBTCC1="\"lib/libtcc1-$T.a\""
+DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
+DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\""
else
-DEF-all += -DTCC_LIBTCC1="\"libtcc1-$T.a\""
+DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
endif
endif
@@ -217,21 +218,22 @@ libtcc.so: LDFLAGS+=-fPIC
# windows dynamic libtcc library
libtcc.dll : $(LIBTCC_OBJ)
$(CC) -shared -o $@ $^ $(LDFLAGS)
+libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
+# import file for windows libtcc.dll
libtcc.def : libtcc.dll tcc$(EXESUF)
- ./tcc$(EXESUF) -impdef $< -o $@
-
-libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
+ $(XTCC) -impdef $< -o $@
+XTCC ?= ./tcc$(EXESUF)
# TinyCC runtime libraries
libtcc1.a : tcc$(EXESUF) FORCE
- @$(MAKE) -C lib DEFINES="$(DEF-$T)"
+ @$(MAKE) -C lib DEFINES='$(DEF-$T)'
# Cross libtcc1.a
-libtcc1-%.a : %-tcc$(EXESUF) FORCE
- @$(MAKE) -C lib DEFINES="$(DEF-$*)" CROSS_TARGET=$*
+%-libtcc1.a : %-tcc$(EXESUF) FORCE
+ @$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$*
-.PRECIOUS: libtcc1-%.a
+.PRECIOUS: %-libtcc1.a
FORCE:
# --------------------------------------------------------------------------
@@ -252,35 +254,29 @@ tcc-doc.info: tcc-doc.texi
INSTALL = install -m644
INSTALLBIN = install -m755 $(STRIP_$(CONFIG_strip))
STRIP_yes = -s
-install-strip: install
-install-strip: CONFIG_strip = yes
-TRY-INSTALL = $(if $(wildcard $1),mkdir -p $2 && $(INSTALL) $1 $2)
-LIBTCC1_W = $(wildcard $(filter %-win32.a %-wince.a,$(LIBTCC1_CROSS)))
-LIBTCC1_U = $(wildcard $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS)))
-PROGS_X = $(wildcard $(PROGS_CROSS))
+LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))
+LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))
+IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2)
+IBw = $(call IB,$(wildcard $1),$2)
+IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2)
+IFw = $(call IF,$(wildcard $1),$2)
+IR = mkdir -p $2 && cp -r $1/. $2
# install progs & libs
install-unx:
- mkdir -p "$(bindir)"
- $(INSTALLBIN) $(PROGS) $(PROGS_X) "$(bindir)"
- mkdir -p "$(tccdir)"
- $(INSTALL) $(LIBTCC1) $(LIBTCC1_U) "$(tccdir)"
- mkdir -p "$(tccdir)/include"
- $(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/include"
- mkdir -p "$(libdir)"
- $(INSTALL) $(LIBTCC) "$(libdir)"
- mkdir -p "$(includedir)"
- $(INSTALL) $(TOPSRC)/libtcc.h "$(includedir)"
- $(call TRY-INSTALL,tcc.1,"$(mandir)/man1")
- $(call TRY-INSTALL,tcc-doc.info,"$(infodir)")
- $(call TRY-INSTALL,tcc-doc.html,"$(docdir)")
-ifneq "$(LIBTCC1_W)" ""
- mkdir -p "$(tccdir)/win32/lib"
- $(INSTALL) $(TOPSRC)/win32/lib/*.def $(LIBTCC1_W) "$(tccdir)/win32/lib"
- mkdir -p "$(tccdir)/win32/include"
- cp -r $(TOPSRC)/win32/include/. "$(tccdir)/win32/include"
- $(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/win32/include"
+ $(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)")
+ $(call IFw,$(LIBTCC1) $(LIBTCC1_U),"$(tccdir)")
+ $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
+ $(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
+ $(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
+ $(call IFw,tcc.1,"$(mandir)/man1")
+ $(call IFw,tcc-doc.info,"$(infodir)")
+ $(call IFw,tcc-doc.html,"$(docdir)")
+ifneq "$(wildcard $(LIBTCC1_W))" ""
+ $(call IFw,$(TOPSRC)/win32/lib/*.def $(LIBTCC1_W),"$(tccdir)/win32/lib")
+ $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/win32/include")
+ $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/win32/include")
endif
# uninstall
@@ -293,32 +289,31 @@ uninstall-unx:
# install progs & libs on windows
install-win:
- mkdir -p "$(tccdir)"
- $(INSTALL) $(PROGS) $(subst libtcc.a,,$(LIBTCC)) $(PROGS_X) "$(tccdir)"
- mkdir -p "$(tccdir)/lib"
- $(INSTALL) $(TOPSRC)/win32/lib/*.def "$(tccdir)/lib"
- $(INSTALL) libtcc1.a $(LIBTCC1_W) "$(tccdir)/lib"
- mkdir -p "$(tccdir)/include"
- cp -r $(TOPSRC)/win32/include/. "$(tccdir)/include"
- $(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/include"
- mkdir -p "$(tccdir)/examples"
- cp -r $(TOPSRC)/win32/examples/. "$(tccdir)/examples"
- $(INSTALL) $(TOPSRC)/tests/libtcc_test.c "$(tccdir)/examples"
- mkdir -p "$(tccdir)/libtcc"
- $(INSTALL) $(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)) "$(tccdir)/libtcc"
- mkdir -p "$(tccdir)/doc"
- $(INSTALL) $(TOPSRC)/win32/tcc-win32.txt $(wildcard tcc-doc.html) "$(tccdir)/doc"
-ifneq "$(LIBTCC1_U)" ""
- $(INSTALL) $(LIBTCC1_U) "$(tccdir)/lib"
- mkdir -p "$(tccdir)/lib/include";
- $(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/lib/include"
+ $(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)")
+ $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
+ $(call IFw,libtcc1.a $(LIBTCC1_W),"$(tccdir)/lib")
+ $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
+ $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
+ $(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")
+ $(call IF,$(TOPSRC)/tests/libtcc_test.c,"$(tccdir)/examples")
+ $(call IFw,$(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)),"$(libdir)")
+ $(call IFw,$(TOPSRC)/win32/tcc-win32.txt tcc-doc.html,"$(docdir)")
+ifneq "$(wildcard $(LIBTCC1_U))" ""
+ $(call IFw,$(LIBTCC1_U),"$(tccdir)/lib")
+ $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/lib/include")
endif
# the msys-git shell works to configure && make except it does not have install
+ifeq ($(CONFIG_WIN32)-$(shell which install >/dev/null 2>&1 || echo no),yes-no)
install-win : INSTALL = cp
+install-win : INSTALLBIN = cp
+endif
# uninstall on windows
uninstall-win:
+ @rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS) libtcc.dll,"$(bindir)/$P")
+ @rm -fv $(foreach F,tcc-doc.html tcc-win32.txt,"$(docdir)/$F")
+ @rm -fv $(foreach F,libtcc.h libtcc.def libtcc.a,"$(libdir)/$F")
rm -r "$(tccdir)"
# --------------------------------------------------------------------------
diff --git a/configure b/configure
index 78f2072..1ee3acb 100755
--- a/configure
+++ b/configure
@@ -56,7 +56,6 @@ case $targetos in
DLLSUF=".dylib"
;;
MINGW*|MSYS*|CYGWIN*)
- confvars="$confvars WIN32"
mingw32=yes
;;
DragonFly|OpenBSD|FreeBSD|NetBSD)
@@ -126,8 +125,6 @@ for opt do
;;
--cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
;;
- --enable-mingw32) confvars="$confvars WIN32"; mingw32="yes"
- ;;
--enable-cross) confvars="$confvars cross"
;;
--disable-static) confvars="$confvars static=no"
@@ -142,6 +139,8 @@ for opt do
;;
--with-selinux) confvars="$confvars selinux"
;;
+ --config-mingw32*) mingw32=$(echo "$opt=yes" | cut -d '=' -f 2)
+ ;;
--config-*) confvars="$confvars ${opt#--config-}"; suggest="no"
;;
--help|-h) show_help="yes"
@@ -216,22 +215,12 @@ if test "$mingw32" = "yes" ; then
if test "$cc" = gcc; then
test -z "$LDFLAGS" && LDFLAGS="-static"
fi
- if test x"$tccdir" = x""; then
- tccdir="tcc"
- fi
- if test -z "$prefix" ; then
- prefix="C:/Program Files/${tccdir}"
- fi
- if test -z "$sharedir" ; then
- sharedir="${prefix}"
- fi
- execprefix="$prefix"
- bindir="${prefix}"
- tccdir="${prefix}"
- libdir="${prefix}/lib"
- docdir="${sharedir}/doc"
- mandir="${sharedir}/man"
- infodir="${sharedir}/info"
+ test -z "$prefix" && prefix="C:/Program Files/tcc"
+ test -z "$tccdir" && tccdir="${prefix}"
+ test -z "$bindir" && bindir="${tccdir}"
+ test -z "$docdir" && docdir="${tccdir}/doc"
+ test -z "$libdir" && libdir="${tccdir}/libtcc"
+ confvars="$confvars WIN32"
LIBSUF=".lib"
EXESUF=".exe"
DLLSUF=".dll"
@@ -263,12 +252,11 @@ else
if test x"$tccdir" = x""; then
tccdir="${libdir}/tcc"
fi
+ if test x"$includedir" = x""; then
+ includedir="${prefix}/include"
+ fi
fi # mingw32
-if test x"$includedir" = x""; then
- includedir="${prefix}/include"
-fi
-
if test x"$show_help" = "xyes" ; then
cat << EOF
Usage: configure [options]
@@ -302,7 +290,6 @@ Advanced options (experts only):
--enable-static make libtcc.a instead of libtcc.dll (win32)
--disable-rpath disable use of -rpath with the above
--with-libgcc use libgcc_s.so.1 instead of libtcc1.a
- --enable-mingw32 build windows version on linux with mingw32
--enable-cross build cross compilers
--with-selinux use mmap for executable memory (with tcc -run)
--sysincludepaths=... specify system include paths, colon separated
@@ -310,7 +297,7 @@ Advanced options (experts only):
--crtprefix=... specify locations of crt?.o, colon separated
--elfinterp=... specify elf interpreter
--triplet=... specify system library/include directory triplet
- --config-uClibc,-musl... enable specific configuration for some systems
+ --config-uClibc,-musl,-mingw32... enable system specific configurations
EOF
#echo "NOTE: The object files are build at the place where configure is launched"
exit 1
@@ -320,15 +307,14 @@ cc="${cross_prefix}${cc}"
ar="${cross_prefix}${ar}"
strip="${cross_prefix}${strip}"
-CONFTEST=./conftest$EXESUF
-if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
- echo "configure: error: '$cc' failed to compile conftest.c."
-else
- gcc_major="$($CONFTEST version)"
- gcc_minor="$($CONFTEST minor)"
-fi
-
if test -z "$cross_prefix" ; then
+ CONFTEST=./conftest$EXESUF
+ if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
+ echo "configure: error: '$cc' failed to compile conftest.c."
+ else
+ gcc_major="$($CONFTEST version)"
+ gcc_minor="$($CONFTEST minor)"
+ fi
bigendian="$($CONFTEST bigendian)"
if test "$mingw32" = "no" ; then
@@ -401,13 +387,13 @@ fi
fcho() { if test -n "$2"; then echo "$1$2"; fi }
-echo "Binary directory $bindir"
-echo "TinyCC directory $tccdir"
-echo "Library directory $libdir"
-echo "Include directory $includedir"
-echo "Manual directory $mandir"
-echo "Info directory $infodir"
-echo "Doc directory $docdir"
+fcho "Binary directory " "$bindir"
+fcho "TinyCC directory " "$tccdir"
+fcho "Library directory " "$libdir"
+fcho "Include directory " "$includedir"
+fcho "Manual directory " "$mandir"
+fcho "Info directory " "$infodir"
+fcho "Doc directory " "$docdir"
fcho "Target root prefix " "$sysroot"
echo "Source path $source_path"
echo "C compiler $cc ($gcc_major.$gcc_minor)"
@@ -471,8 +457,6 @@ print_mak CONFIG_LDDIR "$tcc_lddir"
print_mak CONFIG_TRIPLET "$triplet"
print_mak_int TCC_CPU_VERSION "$cpuver"
-echo "#define GCC_MAJOR $gcc_major" >> $TMPH
-echo "#define GCC_MINOR $gcc_minor" >> $TMPH
if test "$cpu" = "aarch64" ; then
echo "ARCH=arm64" >> config.mak
else
diff --git a/include/stdarg.h b/include/stdarg.h
index a42acae..10ce733 100644
--- a/include/stdarg.h
+++ b/include/stdarg.h
@@ -16,12 +16,7 @@ typedef struct {
char *reg_save_area;
} __va_list_struct;
-/* Avoid conflicting definition for va_list on musl libc */
-#if !defined __DEFINED_va_list || defined __TCC_NEEDS_va_list
typedef __va_list_struct va_list[1];
-#undef __DEFINED_va_list
-#define __DEFINED_va_list
-#endif
void __va_start(__va_list_struct *ap, void *fp);
void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align);
diff --git a/lib/Makefile b/lib/Makefile
index 3b582d4..0c1ec54 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -7,20 +7,20 @@ include $(TOP)/Makefile
VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
-BIN = $(TOP)/libtcc1$(if $(CROSS_TARGET),-$(CROSS_TARGET)).a
+BIN = $(TOP)/$(X)libtcc1.a
-TCC = $(TOP)/$(X)tcc$(EXESUF)
-XCC = $(TCC)
-XAR = $(TCC) -ar
+XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
+XCC = $(XTCC)
+XAR = $(XTCC) -ar
XFLAGS-unx = -B$(TOPSRC)
XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
XFLAGS = $(XFLAGS$(XCFG))
XCFG = $(or $(findstring -win,$T),-unx)
-# in order to use gcc, tyoe: make <target>lib-usegcc=yes
-armlib-usegcc ?= no
+# in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes
+arm-libtcc1-usegcc ?= no
-ifeq "$($(X)$(T)lib-usegcc)" "yes"
+ifeq "$($(T)-libtcc1-usegcc)" "yes"
XCC = $(CC)
XAR = $(AR)
XFLAGS = $(CFLAGS) -fPIC
diff --git a/libtcc.c b/libtcc.c
index 9ef538e..43a07ef 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -104,10 +104,8 @@ static void tcc_set_lib_path_w32(TCCState *s)
char path[1024], *p;
GetModuleFileNameA(tcc_module, path, sizeof path);
p = tcc_basename(normalize_slashes(strlwr(path)));
- if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
- p -= 5;
- else if (p > path)
- p--;
+ if (p > path)
+ --p;
*p = 0;
tcc_set_lib_path(s, path);
}
@@ -440,7 +438,7 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *
CString str;
cstr_new(&str);
- for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) {
+ for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
if (c == '{' && p[1] && p[2] == '}') {
c = p[1], p += 2;
if (c == 'B')
@@ -804,6 +802,8 @@ LIBTCCAPI TCCState *tcc_new(void)
#endif
#elif defined(TCC_TARGET_ARM64)
tcc_define_symbol(s, "__aarch64__", NULL);
+#elif defined TCC_TARGET_C67
+ tcc_define_symbol(s, "__C67__", NULL);
#endif
#ifdef TCC_TARGET_PE
@@ -827,13 +827,13 @@ LIBTCCAPI TCCState *tcc_new(void)
# if defined(__FreeBSD_kernel__)
tcc_define_symbol(s, "__FreeBSD_kernel__", NULL);
# endif
-#endif
# if defined(__NetBSD__)
tcc_define_symbol(s, "__NetBSD__", "__NetBSD__");
# endif
# if defined(__OpenBSD__)
tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__");
# endif
+#endif
/* TinyCC & gcc defines */
#if PTR_SIZE == 4
@@ -853,14 +853,6 @@ LIBTCCAPI TCCState *tcc_new(void)
tcc_define_symbol(s, "__LP64__", NULL);
#endif
-#if defined(TCC_MUSL)
- tcc_define_symbol(s, "__TCC_NEEDS_va_list", "");
- tcc_define_symbol(s, "__builtin_va_list", "va_list");
- tcc_define_symbol(s, "__DEFINED_va_list", "");
- tcc_define_symbol(s, "__DEFINED___isoc_va_list", "");
- tcc_define_symbol(s, "__isoc_va_list", "void *");
-#endif /* TCC_MUSL */
-
#ifdef TCC_TARGET_PE
tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short");
@@ -887,6 +879,11 @@ LIBTCCAPI TCCState *tcc_new(void)
tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)",
"name proto __asm__ (#alias) __THROW");
# endif
+# if defined(TCC_MUSL)
+ tcc_define_symbol(s, "__DEFINED_va_list", "");
+ tcc_define_symbol(s, "__DEFINED___isoc_va_list", "");
+ tcc_define_symbol(s, "__isoc_va_list", "void *");
+# endif /* TCC_MUSL */
/* Some GCC builtins that are simple to express as macros. */
tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
#endif /* ndef TCC_TARGET_PE */
@@ -906,7 +903,6 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
/* free include paths */
dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
- dynarray_reset(&s1->tccinclude_paths, &s1->nb_tccinclude_paths);
dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
dynarray_reset(&s1->cmd_include_files, &s1->nb_cmd_include_files);
@@ -947,7 +943,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
if (!s->nostdinc) {
/* default include paths */
/* -isystem paths have already been handled */
- tcc_add_tccinclude_path(s, CONFIG_TCC_TCCINCLUDEPATHS);
tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
}
@@ -985,12 +980,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
return 0;
}
-LIBTCCAPI int tcc_add_tccinclude_path(TCCState *s, const char *pathname)
-{
- tcc_split_path(s, &s->tccinclude_paths, &s->nb_tccinclude_paths, pathname);
- return 0;
-}
-
LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
{
tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
@@ -1547,7 +1536,6 @@ static const TCCOption tcc_options[] = {
{ "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
{ "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
{ "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
- { "iwithprefix", TCC_OPTION_iwithprefix, TCC_OPTION_HAS_ARG },
{ "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
{ "nostdinc", TCC_OPTION_nostdinc, 0 },
{ "nostdlib", TCC_OPTION_nostdlib, 0 },
@@ -1682,7 +1670,6 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
int last_o = -1;
int x;
CString linker_arg; /* collect -Wl options */
- char buf[1024];
int tool = 0, arg_start = 0, noaction = optind;
char **argv = *pargv;
int argc = *pargc;
@@ -1827,10 +1814,6 @@ reparse:
case TCC_OPTION_isystem:
tcc_add_sysinclude_path(s, optarg);
break;
- case TCC_OPTION_iwithprefix:
- snprintf(buf, sizeof buf, "{B}/%s", optarg);
- tcc_add_tccinclude_path(s, buf);
- break;
case TCC_OPTION_include:
dynarray_add(&s->cmd_include_files,
&s->nb_cmd_include_files, tcc_strdup(optarg));
diff --git a/libtcc.h b/libtcc.h
index fc37251..a1b31e3 100644
--- a/libtcc.h
+++ b/libtcc.h
@@ -32,9 +32,6 @@ LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
/*****************************/
/* preprocessor */
-/* add in tcc include path, searched before anything else */
-LIBTCCAPI int tcc_add_tccinclude_path(TCCState *s, const char *pathname);
-
/* add include path */
LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
diff --git a/tcc.c b/tcc.c
index 53ee84e..c347a06 100644
--- a/tcc.c
+++ b/tcc.c
@@ -86,7 +86,6 @@ static const char help2[] =
" -Wp,-opt same as -opt\n"
" -include file include 'file' above each input file\n"
" -isystem dir add 'dir' to system include path\n"
- " -iwithprefix dir set tcc's private include/library subdir\n"
" -static link to static libraries (not recommended)\n"
" -dumpversion print version\n"
" -print-search-dirs print search paths\n"
@@ -181,7 +180,6 @@ static void print_search_dirs(TCCState *s)
{
printf("install: %s\n", s->tcc_lib_path);
/* print_dirs("programs", NULL, 0); */
- print_dirs("tcc-include", s->tccinclude_paths, s->nb_tccinclude_paths);
print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
print_dirs("libraries", s->library_paths, s->nb_library_paths);
#ifndef TCC_TARGET_PE
@@ -197,7 +195,7 @@ static void set_environment(TCCState *s)
path = getenv("C_INCLUDE_PATH");
if(path != NULL) {
- tcc_add_include_path(s, path);
+ tcc_add_sysinclude_path(s, path);
}
path = getenv("CPATH");
if(path != NULL) {
@@ -278,6 +276,7 @@ redo:
return 0;
if (opt == OPT_PRINT_DIRS) {
/* initialize search dirs */
+ set_environment(s);
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
print_search_dirs(s);
return 0;
diff --git a/tcc.h b/tcc.h
index 32bb608..da26298 100644
--- a/tcc.h
+++ b/tcc.h
@@ -101,10 +101,12 @@ extern long double strtold (const char *__nptr, char **__endptr);
# define IS_DIRSEP(c) (c == '/' || c == '\\')
# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
# define PATHCMP stricmp
+# define PATHSEP ";"
#else
# define IS_DIRSEP(c) (c == '/')
# define IS_ABSPATH(p) IS_DIRSEP(p[0])
# define PATHCMP strcmp
+# define PATHSEP ":"
#endif
/* -------------------------------------------- */
@@ -195,21 +197,14 @@ extern long double strtold (const char *__nptr, char **__endptr);
/* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */
/* system include paths */
-#ifndef CONFIG_TCC_TCCINCLUDEPATHS
+#ifndef CONFIG_TCC_SYSINCLUDEPATHS
# ifdef TCC_TARGET_PE
-# define CONFIG_TCC_TCCINCLUDEPATHS "{B}/include;{B}/include/winapi"
+# define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi"
# else
-# define CONFIG_TCC_TCCINCLUDEPATHS "{B}/include"
-# endif
-#endif
-
-#ifndef CONFIG_TCC_SYSINCLUDEPATHS
-# ifndef TCC_TARGET_PE
# define CONFIG_TCC_SYSINCLUDEPATHS \
- ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
+ "{B}/include" \
+ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
-# else
-# define CONFIG_TCC_SYSINCLUDEPATHS ""
# endif
#endif
@@ -283,12 +278,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
#endif
-#ifdef TCC_TARGET_PE
-#define PATHSEP ';'
-#else
-#define PATHSEP ':'
-#endif
-
/* -------------------------------------------- */
#include "libtcc.h"
@@ -722,10 +711,7 @@ struct TCCState {
DLLReference **loaded_dlls;
int nb_loaded_dlls;
- /* include paths, search order */
- char **tccinclude_paths;
- int nb_tccinclude_paths;
-
+ /* include paths */
char **include_paths;
int nb_include_paths;
@@ -1616,7 +1602,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
-#ifndef TCC_TARGET_ARM
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
#endif
#ifdef TCC_TARGET_X86_64
@@ -1628,7 +1614,6 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
# define ST_PE_IMPORT 0x20
# define ST_PE_STDCALL 0x40
#endif
-
/* ------------ tccrun.c ----------------- */
#ifdef TCC_IS_NATIVE
#ifdef CONFIG_TCC_STATIC
diff --git a/tccasm.c b/tccasm.c
index 1e20dc6..ac1618a 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -75,6 +75,8 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
sym->type.t &= ~VT_EXTERN;
/* Mark that this asm symbol doesn't need to be fed back. */
sym->a.dllimport = 1;
+ } else {
+ sym->type.t |= VT_STATIC;
}
}
return sym;
diff --git a/tccelf.c b/tccelf.c
index 225cd9d..22ce5df 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -828,6 +828,12 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
switch(type) {
#if defined(TCC_TARGET_I386)
case R_386_32:
+ if (!get_sym_attr(s1, sym_index, 0)->dyn_index
+ && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
+ /* don't fixup unresolved (weak) symbols */
+ rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
+ break;
+ }
#elif defined(TCC_TARGET_X86_64)
case R_X86_64_32:
case R_X86_64_32S:
@@ -1238,14 +1244,6 @@ static void tcc_output_binary(TCCState *s1, FILE *f,
}
}
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#define HAVE_PHDR 1
-#define EXTRA_RELITEMS 14
-#else
-#define HAVE_PHDR 1
-#define EXTRA_RELITEMS 9
-#endif
-
ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
{
int sym_index = ELFW(R_SYM) (rel->r_info);
@@ -1413,13 +1411,12 @@ static void bind_libs_dynsyms(TCCState *s1)
for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
sym_index = find_elf_sym(symtab_section, name);
- /* XXX: avoid adding a symbol if already present because of
- -rdynamic ? */
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- if (sym_index && sym->st_shndx != SHN_UNDEF)
- set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
- 0, sym->st_shndx, name);
- else if (esym->st_shndx == SHN_UNDEF) {
+ if (sym_index && sym->st_shndx != SHN_UNDEF
+ && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+ set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
+ sym->st_info, 0, sym->st_shndx, name);
+ } else if (esym->st_shndx == SHN_UNDEF) {
/* weak symbols can stay undefined */
if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
tcc_warning("undefined dynamic symbol '%s'", name);
@@ -1451,10 +1448,11 @@ static void export_global_syms(TCCState *s1)
/* Allocate strings for section names and decide if an unallocated section
should be output.
NOTE: the strsec section comes last, so its size is also correct ! */
-static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
+static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
{
int i;
Section *s;
+ int textrel = 0;
/* Allocate strings for section names */
for(i = 1; i < s1->nb_sections; i++) {
@@ -1463,12 +1461,11 @@ static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
patch them */
if (file_type == TCC_OUTPUT_DLL &&
s->sh_type == SHT_RELX &&
- !(s->sh_flags & SHF_ALLOC)) {
- /* gr: avoid bogus relocs for empty (debug) sections */
- if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
- prepare_dynamic_rel(s1, s);
- else if (s1->do_debug)
- s->sh_size = s->data_offset;
+ !(s->sh_flags & SHF_ALLOC) &&
+ (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
+ prepare_dynamic_rel(s1, s)) {
+ if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
+ textrel = 1;
} else if (s1->do_debug ||
file_type == TCC_OUTPUT_OBJ ||
(s->sh_flags & SHF_ALLOC) ||
@@ -1480,13 +1477,14 @@ static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
s->sh_name = put_elf_str(strsec, s->name);
}
strsec->sh_size = strsec->data_offset;
+ return textrel;
}
/* Info to be copied in dynamic section */
struct dyn_inf {
Section *dynamic;
Section *dynstr;
- unsigned long dyn_rel_off;
+ unsigned long data_offset;
addr_t rel_addr;
addr_t rel_size;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -1542,7 +1540,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
the program header table itself if needed. These are done later as
they require section layout to be done first. */
if (interp)
- ph += 1 + HAVE_PHDR;
+ ph += 2;
/* dynamic relocation table information, for .dynamic section */
dyninf->rel_addr = dyninf->rel_size = 0;
@@ -1684,19 +1682,14 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
if (interp) {
ph = &phdr[0];
- if (HAVE_PHDR)
- {
- int len = phnum * sizeof(ElfW(Phdr));
-
- ph->p_type = PT_PHDR;
- ph->p_offset = sizeof(ElfW(Ehdr));
- ph->p_vaddr = interp->sh_addr - len;
- ph->p_paddr = ph->p_vaddr;
- ph->p_filesz = ph->p_memsz = len;
- ph->p_flags = PF_R | PF_X;
- ph->p_align = 4; /* interp->sh_addralign; */
- ph++;
- }
+ ph->p_type = PT_PHDR;
+ ph->p_offset = sizeof(ElfW(Ehdr));
+ ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
+ ph->p_vaddr = interp->sh_addr - ph->p_filesz;
+ ph->p_paddr = ph->p_vaddr;
+ ph->p_flags = PF_R | PF_X;
+ ph->p_align = 4; /* interp->sh_addralign; */
+ ph++;
ph->p_type = PT_INTERP;
ph->p_offset = interp->sh_offset;
@@ -1727,12 +1720,9 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
sections */
static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
{
- Section *dynamic;
-
- dynamic = dyninf->dynamic;
+ Section *dynamic = dyninf->dynamic;
/* put dynamic section entries */
- dynamic->data_offset = dyninf->dyn_rel_off;
put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
@@ -2009,22 +1999,20 @@ static int elf_output_file(TCCState *s1, const char *filename)
ElfW(Phdr) *phdr;
ElfW(Sym) *sym;
Section *strsec, *interp, *dynamic, *dynstr;
+ int textrel;
file_type = s1->output_type;
s1->nb_errors = 0;
-
- /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
- if (file_type != TCC_OUTPUT_OBJ) {
- tcc_add_runtime(s1);
- }
-
+ ret = -1;
phdr = NULL;
sec_order = NULL;
interp = dynamic = dynstr = NULL; /* avoid warning */
+ textrel = 0;
if (file_type != TCC_OUTPUT_OBJ) {
+ /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
+ tcc_add_runtime(s1);
relocate_common_syms();
-
tcc_add_linker_symbols(s1);
if (!s1->static_link) {
@@ -2057,52 +2045,69 @@ static int elf_output_file(TCCState *s1, const char *filename)
if (file_type == TCC_OUTPUT_EXE) {
bind_exe_dynsyms(s1);
-
- if (s1->nb_errors) {
- ret = -1;
+ if (s1->nb_errors)
goto the_end;
- }
-
bind_libs_dynsyms(s1);
- } else /* shared library case: simply export all global symbols */
+ } else {
+ /* shared library case: simply export all global symbols */
export_global_syms(s1);
+ }
+ }
+ build_got_entries(s1);
+ }
- build_got_entries(s1);
+ /* we add a section for symbols */
+ strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
+ put_elf_str(strsec, "");
- /* add a list of needed dlls */
- for(i = 0; i < s1->nb_loaded_dlls; i++) {
- DLLReference *dllref = s1->loaded_dlls[i];
- if (dllref->level == 0)
- put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
- }
+ /* Allocate strings for section names */
+ textrel = alloc_sec_names(s1, file_type, strsec);
- if (s1->rpath)
- put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
- put_elf_str(dynstr, s1->rpath));
+ if (dynamic) {
+ /* add a list of needed dlls */
+ for(i = 0; i < s1->nb_loaded_dlls; i++) {
+ DLLReference *dllref = s1->loaded_dlls[i];
+ if (dllref->level == 0)
+ put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
+ }
+
+ if (s1->rpath)
+ put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
+ put_elf_str(dynstr, s1->rpath));
+ if (file_type == TCC_OUTPUT_DLL) {
+ if (s1->soname)
+ put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
/* XXX: currently, since we do not handle PIC code, we
must relocate the readonly segments */
- if (file_type == TCC_OUTPUT_DLL) {
- if (s1->soname)
- put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
+ if (textrel)
put_dt(dynamic, DT_TEXTREL, 0);
- }
+ }
- if (s1->symbolic)
- put_dt(dynamic, DT_SYMBOLIC, 0);
+ if (s1->symbolic)
+ put_dt(dynamic, DT_SYMBOLIC, 0);
- /* add necessary space for other entries */
- dyninf.dyn_rel_off = dynamic->data_offset;
- dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
- } else {
- /* still need to build got entries in case of static link */
- build_got_entries(s1);
- }
+ dyninf.dynamic = dynamic;
+ dyninf.dynstr = dynstr;
+ /* remember offset and reserve space for 2nd call below */
+ dyninf.data_offset = dynamic->data_offset;
+ fill_dynamic(s1, &dyninf);
+ dynamic->sh_size = dynamic->data_offset;
+ dynstr->sh_size = dynstr->data_offset;
}
- /* we add a section for symbols */
- strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
- put_elf_str(strsec, "");
+ /* compute number of program headers */
+ if (file_type == TCC_OUTPUT_OBJ)
+ phnum = 0;
+ else if (file_type == TCC_OUTPUT_DLL)
+ phnum = 3;
+ else if (s1->static_link)
+ phnum = 2;
+ else
+ phnum = 5;
+
+ /* allocate program segment headers */
+ phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
/* compute number of sections */
shnum = s1->nb_sections;
@@ -2111,41 +2116,16 @@ static int elf_output_file(TCCState *s1, const char *filename)
sec_order = tcc_malloc(sizeof(int) * shnum);
sec_order[0] = 0;
- /* compute number of program headers */
- switch(file_type) {
- default:
- case TCC_OUTPUT_OBJ:
- phnum = 0;
- break;
- case TCC_OUTPUT_EXE:
- if (!s1->static_link)
- phnum = 4 + HAVE_PHDR;
- else
- phnum = 2;
- break;
- case TCC_OUTPUT_DLL:
- phnum = 3;
- break;
- }
-
- /* Allocate strings for section names */
- alloc_sec_names(s1, file_type, strsec);
-
- /* allocate program segment headers */
- phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
-
/* compute section to program header mapping */
file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
sec_order);
/* Fill remaining program header and finalize relocation related to dynamic
linking. */
- if (phnum > 0) {
+ if (file_type != TCC_OUTPUT_OBJ) {
fill_unloadable_phdr(phdr, phnum, interp, dynamic);
if (dynamic) {
- dyninf.dynamic = dynamic;
- dyninf.dynstr = dynstr;
-
+ dynamic->data_offset = dyninf.data_offset;
fill_dynamic(s1, &dyninf);
/* put in GOT the dynamic section address and relocate PLT */
@@ -2162,22 +2142,20 @@ static int elf_output_file(TCCState *s1, const char *filename)
}
}
}
- }
- /* if building executable or DLL, then relocate each section
- except the GOT which is already relocated */
- if (file_type != TCC_OUTPUT_OBJ) {
+ /* if building executable or DLL, then relocate each section
+ except the GOT which is already relocated */
ret = final_sections_reloc(s1);
if (ret)
goto the_end;
tidy_section_headers(s1, sec_order);
- }
- /* Perform relocation to GOT or PLT entries */
- if (file_type == TCC_OUTPUT_EXE && s1->static_link)
- fill_got(s1);
- else if (s1->got)
- fill_local_got_entries(s1);
+ /* Perform relocation to GOT or PLT entries */
+ if (file_type == TCC_OUTPUT_EXE && s1->static_link)
+ fill_got(s1);
+ else if (s1->got)
+ fill_local_got_entries(s1);
+ }
/* Create the ELF file with name 'filename' */
ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
diff --git a/tccgen.c b/tccgen.c
index 02e40de..7d554b5 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -116,6 +116,12 @@ ST_FUNC int ieee_finite(double d)
return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
}
+/* compiling intel long double natively */
+#if (defined __i386__ || defined __x86_64__) \
+ && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
+# define TCC_IS_NATIVE_387
+#endif
+
ST_FUNC void test_lvalue(void)
{
if (!(vtop->r & VT_LVAL))
@@ -267,9 +273,6 @@ ST_FUNC int tccgen_compile(TCCState *s1)
parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
next();
decl(VT_CONST);
- if (tok != TOK_EOF)
- expect("declaration");
-
gen_inline_functions(s1);
check_vstack();
/* end of translation unit info */
@@ -2411,6 +2414,9 @@ static void gen_cast(CType *type)
df = is_float(dbt);
c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
+#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
+ c &= dbt != VT_LDOUBLE;
+#endif
if (c) {
/* constant case: we can do it now */
/* XXX: in ISOC, cannot do it if error in convert */
@@ -3096,6 +3102,8 @@ ST_FUNC void vstore(void)
/* ... and discard */
vpop();
}
+ } else if (dbt == VT_VOID) {
+ --vtop;
} else {
#ifdef CONFIG_TCC_BCHECK
/* bound check case */
@@ -5925,7 +5933,10 @@ static void block(int *bsym, int *csym, int is_expr)
if (tok != ';') {
gexpr();
gen_assign_cast(&func_vt);
- gfunc_return(&func_vt);
+ if ((func_vt.t & VT_BTYPE) == VT_VOID)
+ vtop--;
+ else
+ gfunc_return(&func_vt);
}
skip(';');
/* jump unless last stmt in top-level block */
@@ -6483,7 +6494,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
*(double *)ptr = vtop->c.d;
break;
case VT_LDOUBLE:
-#if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
+#if defined TCC_IS_NATIVE_387
if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
memcpy(ptr, &vtop->c.ld, 10);
#ifdef __TINYC__
@@ -7091,17 +7102,22 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym)
next();
continue;
}
- if (l == VT_CONST &&
- (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
+ if (l != VT_CONST)
+ break;
+ if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
/* global asm block */
asm_global_instr();
continue;
}
- /* special test for old K&R protos without explicit int
- type. Only accepted when defining global data */
- if (l != VT_CONST || tok < TOK_UIDENT)
+ if (tok >= TOK_UIDENT) {
+ /* special test for old K&R protos without explicit int
+ type. Only accepted when defining global data */
+ btype.t = VT_INT;
+ } else {
+ if (tok != TOK_EOF)
+ expect("declaration");
break;
- btype.t = VT_INT;
+ }
}
if (tok == ';') {
if ((btype.t & VT_BTYPE) == VT_STRUCT) {
diff --git a/tccpe.c b/tccpe.c
index 366f0e7..a67023d 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -26,10 +26,12 @@
#ifndef _WIN32
#define stricmp strcasecmp
#define strnicmp strncasecmp
+#include <sys/stat.h> /* chmod() */
#endif
#ifdef TCC_TARGET_X86_64
# define ADDR3264 ULONGLONG
+# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
# define REL_TYPE_DIRECT R_X86_64_64
# define R_XXX_THUNKFIX R_X86_64_PC32
# define R_XXX_RELATIVE R_X86_64_RELATIVE
@@ -38,6 +40,7 @@
#elif defined TCC_TARGET_ARM
# define ADDR3264 DWORD
+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
# define REL_TYPE_DIRECT R_ARM_ABS32
# define R_XXX_THUNKFIX R_ARM_ABS32
# define R_XXX_RELATIVE R_ARM_RELATIVE
@@ -46,6 +49,7 @@
#elif defined TCC_TARGET_I386
# define ADDR3264 DWORD
+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
# define REL_TYPE_DIRECT R_386_32
# define R_XXX_THUNKFIX R_386_32
# define R_XXX_RELATIVE R_386_RELATIVE
@@ -54,22 +58,6 @@
#endif
-#if 0
-#ifdef _WIN32
-void dbg_printf (const char *fmt, ...)
-{
- char buffer[4000];
- va_list arg;
- int x;
- va_start(arg, fmt);
- x = vsprintf (buffer, fmt, arg);
- strcpy(buffer+x, "\n");
- OutputDebugString(buffer);
-}
-#endif
-#endif
-
-/* ----------------------------------------------------------- */
#ifndef IMAGE_NT_SIGNATURE
/* ----------------------------------------------------------- */
/* definitions below are from winnt.h */
@@ -241,14 +229,19 @@ typedef struct _IMAGE_BASE_RELOCATION {
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_SECTION 6
#define IMAGE_REL_BASED_REL32 7
+#define IMAGE_REL_BASED_DIR64 10
#pragma pack(pop)
/* ----------------------------------------------------------- */
#endif /* ndef IMAGE_NT_SIGNATURE */
/* ----------------------------------------------------------- */
-#pragma pack(push, 1)
+#ifndef IMAGE_REL_BASED_DIR64
+# define IMAGE_REL_BASED_DIR64 10
+#endif
+
+#pragma pack(push, 1)
struct pe_header
{
IMAGE_DOS_HEADER doshdr;
@@ -281,7 +274,6 @@ struct pe_rsrc_reloc {
DWORD size;
WORD type;
};
-
#pragma pack(pop)
/* ------------------------------------------------------------- */
@@ -732,6 +724,9 @@ static int pe_write(struct pe_info *pe)
fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET);
pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL);
fclose (op);
+#ifndef _WIN32
+ chmod(pe->filename, 0777);
+#endif
if (2 == pe->s1->verbose)
printf("-------------------------------\n");
@@ -1017,7 +1012,7 @@ static void pe_build_reloc (struct pe_info *pe)
}
if ((addr -= offset) < (1<<12)) { /* one block spans 4k addresses */
WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD));
- *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12;
+ *wp = addr | PE_IMAGE_REL<<12;
++count;
continue;
}
@@ -1471,7 +1466,7 @@ static void pe_print_sections(TCCState *s1, const char *fname)
/* ------------------------------------------------------------- */
/* helper function for load/store to insert one more indirection */
-#ifndef TCC_TARGET_ARM
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
{
int r2;
diff --git a/tccpp.c b/tccpp.c
index 3d11dc3..76f9e42 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -591,7 +591,7 @@ ST_FUNC int handle_eob(void)
/* only tries to read if really end of buffer */
if (bf->buf_ptr >= bf->buf_end) {
- if (bf->fd != -1) {
+ if (bf->fd >= 0) {
#if defined(PARSE_DEBUG)
len = 1;
#else
@@ -1803,8 +1803,7 @@ ST_FUNC void preprocess(int is_bof)
/* store current file in stack, but increment stack later below */
*s1->include_stack_ptr = file;
i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0;
- n = 2 + s1->nb_tccinclude_paths + s1->nb_include_paths +
- s1->nb_sysinclude_paths;
+ n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths;
for (; i < n; ++i) {
char buf1[sizeof file->filename];
CachedInclude *e;
@@ -1826,14 +1825,8 @@ ST_FUNC void preprocess(int is_bof)
} else {
/* search in all the include paths */
- int k, j = i - 2;
-
- if (j < (k = s1->nb_tccinclude_paths))
- path = s1->tccinclude_paths[j];
- else if ((j -= k) < s1->nb_include_paths)
- path = s1->include_paths[j];
- else if ((j -= s1->nb_include_paths) < s1->nb_sysinclude_paths)
- path = s1->sysinclude_paths[j];
+ int j = i - 2, k = j - s1->nb_include_paths;
+ path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k];
pstrcpy(buf1, sizeof(buf1), path);
pstrcat(buf1, sizeof(buf1), "/");
}
@@ -2635,6 +2628,8 @@ static inline void next_nomacro1(void)
tcc_close();
s1->include_stack_ptr--;
p = file->buf_ptr;
+ if (p == file->buffer)
+ tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL;
goto redo_no_start;
}
}
@@ -2968,7 +2963,7 @@ maybe_newline:
keep_tok_flags:
file->buf_ptr = p;
#if defined(PARSE_DEBUG)
- printf("token = %s\n", get_tok_str(tok, &tokc));
+ printf("token = %d %s\n", tok, get_tok_str(tok, &tokc));
#endif
}
@@ -3585,7 +3580,8 @@ ST_INLN void unget_tok(int last_tok)
ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
{
- char *buf;
+ CString cstr;
+ int i;
s1->include_stack_ptr = s1->include_stack;
s1->ifdef_stack_ptr = s1->ifdef_stack;
@@ -3601,25 +3597,24 @@ ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
set_idnum('.', is_asm ? IS_ID : 0);
- buf = tcc_malloc(3 + strlen(file->filename));
- sprintf(buf, "\"%s\"", file->filename);
- tcc_define_symbol(s1, "__BASE_FILE__", buf);
- tcc_free(buf);
+ cstr_new(&cstr);
+ cstr_cat(&cstr, "\"", -1);
+ cstr_cat(&cstr, file->filename, -1);
+ cstr_cat(&cstr, "\"", 0);
+ tcc_define_symbol(s1, "__BASE_FILE__", cstr.data);
- if (s1->nb_cmd_include_files) {
- CString cstr;
- int i;
- cstr_new(&cstr);
- for (i = 0; i < s1->nb_cmd_include_files; i++) {
- cstr_cat(&cstr, "#include \"", -1);
- cstr_cat(&cstr, s1->cmd_include_files[i], -1);
- cstr_cat(&cstr, "\"\n", -1);
- }
+ cstr_reset(&cstr);
+ for (i = 0; i < s1->nb_cmd_include_files; i++) {
+ cstr_cat(&cstr, "#include \"", -1);
+ cstr_cat(&cstr, s1->cmd_include_files[i], -1);
+ cstr_cat(&cstr, "\"\n", -1);
+ }
+ if (cstr.size) {
*s1->include_stack_ptr++ = file;
tcc_open_bf(s1, "<command line>", cstr.size);
memcpy(file->buffer, cstr.data, cstr.size);
- cstr_free(&cstr);
}
+ cstr_free(&cstr);
if (is_asm)
tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
diff --git a/tccrun.c b/tccrun.c
index 85957b8..b9a052b 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -45,15 +45,13 @@ static void set_exception_handler(void);
#endif
static void set_pages_executable(void *ptr, unsigned long length);
-static int tcc_relocate_ex(TCCState *s1, void *ptr);
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
#ifdef _WIN64
static void *win64_add_function_table(TCCState *s1);
static void win64_del_function_table(void *);
#endif
-// #define HAVE_SELINUX
-
/* ------------------------------------------------------------- */
/* Do all relocations (needed before using tcc_get_symbol())
Returns -1 on error. */
@@ -61,25 +59,36 @@ static void win64_del_function_table(void *);
LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
{
int size;
+ addr_t ptr_diff = 0;
if (TCC_RELOCATE_AUTO != ptr)
- return tcc_relocate_ex(s1, ptr);
+ return tcc_relocate_ex(s1, ptr, 0);
- size = tcc_relocate_ex(s1, NULL);
+ size = tcc_relocate_ex(s1, NULL, 0);
if (size < 0)
return -1;
#ifdef HAVE_SELINUX
- /* Use mmap instead of malloc for Selinux. */
- ptr = mmap (NULL, size, PROT_READ|PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (ptr == MAP_FAILED)
- tcc_error("tccrun: could not map memory");
+{
+ /* Using mmap instead of malloc */
+ void *prx;
+ char tmpfname[] = "/tmp/.tccrunXXXXXX";
+ int fd = mkstemp(tmpfname);
+ unlink(tmpfname);
+ ftruncate(fd, size);
+
+ ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED || prx == MAP_FAILED)
+ tcc_error("tccrun: could not map memory");
dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
+ dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx);
+ ptr_diff = (char*)prx - (char*)ptr;
+}
#else
ptr = tcc_malloc(size);
#endif
- tcc_relocate_ex(s1, ptr); /* no more errors expected */
+ tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
return 0;
}
@@ -91,6 +100,7 @@ ST_FUNC void tcc_run_free(TCCState *s1)
for (i = 0; i < s1->nb_runtime_mem; ++i) {
#ifdef HAVE_SELINUX
unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++];
+ munmap(s1->runtime_mem[i++], size);
munmap(s1->runtime_mem[i], size);
#else
#ifdef _WIN64
@@ -166,7 +176,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
/* relocate code. Return -1 on error, required size if ptr is NULL,
otherwise copy code into buffer passed by the caller */
-static int tcc_relocate_ex(TCCState *s1, void *ptr)
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
{
Section *s;
unsigned offset, length, fill, i, k;
@@ -199,7 +209,12 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
if (k != !(s->sh_flags & SHF_EXECINSTR))
continue;
offset += fill;
- s->sh_addr = mem ? mem + offset : 0;
+ if (!mem)
+ s->sh_addr = 0;
+ else if (s->sh_flags & SHF_EXECINSTR)
+ s->sh_addr = mem + offset + ptr_diff;
+ else
+ s->sh_addr = mem + offset;
#if 0
if (mem)
printf("%-16s +%02lx %p %04x\n",
@@ -242,13 +257,15 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
continue;
length = s->data_offset;
ptr = (void*)s->sh_addr;
+ if (s->sh_flags & SHF_EXECINSTR)
+ ptr = (char*)ptr - ptr_diff;
if (NULL == s->data || s->sh_type == SHT_NOBITS)
memset(ptr, 0, length);
else
memcpy(ptr, s->data, length);
/* mark executable sections as executable in memory */
if (s->sh_flags & SHF_EXECINSTR)
- set_pages_executable(ptr, length);
+ set_pages_executable((char*)ptr + ptr_diff, length);
}
return 0;
}
@@ -263,15 +280,17 @@ static void set_pages_executable(void *ptr, unsigned long length)
VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
#else
void __clear_cache(void *beginning, void *end);
+# ifndef HAVE_SELINUX
addr_t start, end;
-#ifndef PAGESIZE
-# define PAGESIZE 4096
-#endif
+# ifndef PAGESIZE
+# define PAGESIZE 4096
+# endif
start = (addr_t)ptr & ~(PAGESIZE - 1);
end = (addr_t)ptr + length;
end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
tcc_error("mprotect failed: did you mean to configure --with-selinux?");
+# endif
# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
__clear_cache(ptr, (char *)ptr + length);
# endif
diff --git a/tcctok.h b/tcctok.h
index 5380ff3..317f64c 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -120,6 +120,8 @@
DEF(TOK_FASTCALL1, "fastcall")
DEF(TOK_FASTCALL2, "__fastcall")
DEF(TOK_FASTCALL3, "__fastcall__")
+ DEF(TOK_REGPARM1, "regparm")
+ DEF(TOK_REGPARM2, "__regparm__")
DEF(TOK_MODE, "__mode__")
DEF(TOK_MODE_QI, "__QI__")
@@ -134,23 +136,19 @@
DEF(TOK_NORETURN2, "__noreturn__")
DEF(TOK_VISIBILITY1, "visibility")
DEF(TOK_VISIBILITY2, "__visibility__")
+
DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
DEF(TOK_builtin_choose_expr, "__builtin_choose_expr")
DEF(TOK_builtin_constant_p, "__builtin_constant_p")
DEF(TOK_builtin_frame_address, "__builtin_frame_address")
DEF(TOK_builtin_return_address, "__builtin_return_address")
DEF(TOK_builtin_expect, "__builtin_expect")
-#ifdef TCC_TARGET_X86_64
-#ifdef TCC_TARGET_PE
+ /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
+#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
DEF(TOK_builtin_va_start, "__builtin_va_start")
-#else
+#elif defined TCC_TARGET_X86_64
DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
-#endif
-#endif
- DEF(TOK_REGPARM1, "regparm")
- DEF(TOK_REGPARM2, "__regparm__")
-
-#ifdef TCC_TARGET_ARM64
+#elif defined TCC_TARGET_ARM64
DEF(TOK___va_start, "__va_start")
DEF(TOK___va_arg, "__va_arg")
#endif
diff --git a/tests/Makefile b/tests/Makefile
index 39dee7f..6a61717 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -234,8 +234,12 @@ vla_test-run: vla_test$(EXESUF)
cross-test :
@echo ------------ $@ ------------
$(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
$(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
$(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/arm64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
$(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
$(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
$(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
diff --git a/tests/pp/13.expect b/tests/pp/13.expect
index 6eb2bec..c7a3230 100644
--- a/tests/pp/13.expect
+++ b/tests/pp/13.expect
@@ -1,3 +1,2 @@
-# `modelist' label. Each video mode record looks like:
.text
endtext:
diff --git a/tests/pp/15.c b/tests/pp/15.c
index 3bbc3ca..cf13f9a 100644
--- a/tests/pp/15.c
+++ b/tests/pp/15.c
@@ -12,7 +12,7 @@ return n(A)n(++)n(+)n(+)n(B);
return n(0x1E)n(-1);
// unlike gcc but correct
-XXX: return n(x)+n(x)-n(1)+n(1)-2;
+// XXX: return n(x)+n(x)-n(1)+n(1)-2;
// unlike gcc, but cannot appear in valid C
-XXX: return n(x)n(x)n(1)n(2)n(x);
+// XXX: return n(x)n(x)n(1)n(2)n(x);
diff --git a/tests/pp/15.expect b/tests/pp/15.expect
index f652240..b4f885e 100644
--- a/tests/pp/15.expect
+++ b/tests/pp/15.expect
@@ -3,5 +3,3 @@ return A+++B;
return A+ ++B;
return A+++ +B;
return 0x1E -1;
-XXX: return x+x-1 +1 -2;
-XXX: return x x 1 2 x;
diff --git a/tests/pp/Makefile b/tests/pp/Makefile
index 21c9969..687aa52 100644
--- a/tests/pp/Makefile
+++ b/tests/pp/Makefile
@@ -12,7 +12,7 @@ TESTS = $(call files,c) $(call files,S)
all test : $(sort $(TESTS))
-DIFF_OPTS = -Nu -b -B -I "^\#"
+DIFF_OPTS = -Nu -b -B
# Filter source directory in warnings/errors (out-of-tree builds)
FILTER = 2>&1 | sed 's,$(SRC)/,,g'
@@ -40,7 +40,7 @@ clean:
rm -f *.output
02.test : DIFF_OPTS += -w
-15.test : DIFF_OPTS += -I"^XXX:"
+# 15.test : DIFF_OPTS += -I"^XXX:"
# diff options:
# -b ighore space changes
diff --git a/tests/tcctest.c b/tests/tcctest.c
index 7877243..099fc35 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -3235,6 +3235,7 @@ void asm_local_statics (void)
}
#endif
+static
unsigned int set;
void fancy_copy (unsigned *in, unsigned *out)
@@ -3247,7 +3248,7 @@ void fancy_copy2 (unsigned *in, unsigned *out)
asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
}
-#ifdef __x86_64__
+#if defined __x86_64__ && !defined _WIN64
void clobber_r12(void)
{
asm volatile("mov $1, %%r12" ::: "r12");
@@ -3256,7 +3257,7 @@ void clobber_r12(void)
void test_high_clobbers(void)
{
-#ifdef __x86_64__
+#if defined __x86_64__ && !defined _WIN64
register long val asm("r12");
long val2;
/* This tests if asm clobbers correctly save/restore callee saved
@@ -3265,11 +3266,9 @@ void test_high_clobbers(void)
correctly capture the data flow, but good enough for us. */
asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
clobber_r12();
-#ifndef _WIN64
asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
printf("asmhc: 0x%x\n", val2);
#endif
-#endif
}
static long cpu_number;
diff --git a/tests/tests2/95_bitfields.c b/tests/tests2/95_bitfields.c
index 683becf..f025c57 100644
--- a/tests/tests2/95_bitfields.c
+++ b/tests/tests2/95_bitfields.c
@@ -70,7 +70,7 @@
{
struct M P __s {
int a;
- char b;
+ signed char b;
int x : 12, y : 4, : 0, : 4, z : 3;
char d;
};
diff --git a/tests/tests2/96_nodata_wanted.c b/tests/tests2/96_nodata_wanted.c
index b594938..cc211d3 100644
--- a/tests/tests2/96_nodata_wanted.c
+++ b/tests/tests2/96_nodata_wanted.c
@@ -78,7 +78,7 @@ te1:;
tl += &&te1 - &&ts1;
printf("size of data/text:\n %s/%s\n",
dl ? "non-zero":"zero", tl ? "non-zero":"zero");
- printf("# %d/%d\n", dl, tl);
+ /*printf("# %d/%d\n", dl, tl);*/
}
#endif
diff --git a/tests/tests2/96_nodata_wanted.expect b/tests/tests2/96_nodata_wanted.expect
index 6e54f24..2749109 100644
--- a/tests/tests2/96_nodata_wanted.expect
+++ b/tests/tests2/96_nodata_wanted.expect
@@ -17,9 +17,7 @@ data:
333 44 555555 6 7
size of data/text:
non-zero/non-zero
-# 111/193
[test_data_suppression_on]
size of data/text:
zero/zero
-# 0/0
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
index 6bff618..190b2d9 100644
--- a/tests/tests2/Makefile
+++ b/tests/tests2/Makefile
@@ -70,7 +70,7 @@ all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ;
T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS)
T2 = $(TCC) $(FLAGS) -run $< $(ARGS)
T3 = $(FILTER) >$*.output 2>&1 || true \
- && diff -Nbu -I "^\#" $(filter %.expect,$^) $*.output \
+ && diff -Nbu $(filter %.expect,$^) $*.output \
&& rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
# run single test and update .expect file, e.g. "make tests2.37+"
diff --git a/win32/Makefile b/win32/Makefile
deleted file mode 100644
index 5bd60bd..0000000
--- a/win32/Makefile
+++ /dev/null
@@ -1,148 +0,0 @@
-#
-# This Makefile builds native Windows tcc for both 32 and 64 bits generator.
-# It requires Cygwin 64 and gcc to bootstrap a first tcc version which is used
-# by a second stage to compile tcc it self.
-# Generated binaries do not require cygwin to run.
-# You can launch 'tarball' target to build a tar.gz you can install on any
-# Windows machines.
-
-CPU = $(shell if `gcc -v 2>&1 | grep Target | grep -q x86_64`; then echo 64; else echo 32; fi)
-VERSION = $(shell cat ../VERSION)
-BOOTCC = gcc
-CFLAGS = -s -static -fno-strict-aliasing -Wno-incompatible-pointer-types -DTCC_TARGET_PE
-#WINPWD = `cygpath --mixed $(PWD)`
-#@echo "#define CONFIG_TCCDIR \"$(WINPWD)\""
-
-ifeq ($(CPU), 64)
-NATIVE = -m$(CPU) -DTCC_TARGET_X86_64
-ARCH = x86_64
-else
-NATIVE = -m$(CPU) -DTCC_TARGET_I386
-ARCH = i386
-endif
-
-TARGET = $(CPU)
-
-ifeq ($(TARGET), 64)
-TFLAGS = -m$(TARGET) -DTCC_TARGET_X86_64
-TARCH = x86_64
-else
-TFLAGS = -m$(TARGET) -DTCC_TARGET_I386
-TARCH = i386
-endif
-
-all: pre bootstrap libs rebuild
- @chmod 775 *.exe
- @ls -ls *.exe
-
-pre:
- @echo ARCH=$(TARCH) 1> ../config.mak
- @echo TARGETOS=Windows 1>> ../config.mak
- @echo CONFIG_WIN32=yes 1>> ../config.mak
- @echo TOPSRC=$$\(TOP\) 1>> ../config.mak
- @echo "#define TCC_VERSION \"$(VERSION)\"" 1>../config.h
- @echo "#ifdef TCC_TARGET_X86_64" 1>>../config.h
- @echo "#define TCC_LIBTCC1 \"libtcc1-64.a\"" 1>>../config.h
- @echo "#else" 1>>../config.h
- @echo "#define TCC_LIBTCC1 \"libtcc1-32.a\"" 1>>../config.h
- @echo "#endif" 1>>../config.h
- @echo @set VERSION $(VERSION) 1>../config.texi
- @rm -f *tcc.exe tiny_*.exe *tcc.dll lib/*.a
- @rm -r -f libtcc doc
- @mkdir libtcc
- @mkdir doc
- @cp ../include/*.h include
- @cp ../tcclib.h include
- @cp ../libtcc.h include
- @cp tcc-win32.txt doc
- @cp ../tests/libtcc_test.c examples
-
-PHONY += pre
-
-bootstrap:
- @echo Bootstrapping 32bits and 64bits tools with $(BOOTCC) -m$(CPU)
- @$(BOOTCC) $(CFLAGS) -DTCC_TARGET_I386 -o i386-win32-tcc.exe ../tcc.c
- @$(BOOTCC) $(CFLAGS) -DTCC_TARGET_X86_64 -o x86_64-win32-tcc.exe ../tcc.c
- @$(BOOTCC) $(CFLAGS) $(NATIVE) -o tcc.exe ../tcc.c
- @$(BOOTCC) $(CFLAGS) $(NATIVE) -DLIBTCC_AS_DLL -o libtcc.dll -shared ../libtcc.c
-
-PHONY += bootstrap
-
-lib/libtcc1-32.a:
- @echo Building $*.a with tcc -m32
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/libtcc1.c
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/alloca86.S
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/alloca86-bt.S
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/crt1.c
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/crt1w.c
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/wincrt1.c
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/wincrt1w.c
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/dllcrt1.c
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/dllmain.c
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/chkstk.S
- @./tcc -m32 -ar lib/libtcc1-32.a libtcc1.o alloca86.o alloca86-bt.o crt1.o wincrt1.o crt1w.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o
- @rm *.o
-
-lib/libtcc1-64.a:
- @echo Building $*.a with tcc -m64
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/libtcc1.c
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/alloca86_64.S
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/alloca86_64-bt.S
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/crt1.c
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/crt1w.c
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/wincrt1.c
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/wincrt1w.c
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/dllcrt1.c
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/dllmain.c
- @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/chkstk.S
- @./tcc -m64 -ar lib/libtcc1-64.a libtcc1.o alloca86_64.o alloca86_64-bt.o crt1.o wincrt1.o crt1w.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o
- @rm *.o
-
-libs: lib/libtcc1-32.a lib/libtcc1-64.a
-
-PHONY += libs
-
-rebuild:
- @echo Rebuild using tcc itself - default $(TARGET)bits
- @./$(TARCH)-win32-tcc -O2 -B. $(TFLAGS) -DTCC_TARGET_PE -o tcc.exe ../tcc.c
- @./tcc -O2 -B. $(TFLAGS) -DTCC_TARGET_PE -DLIBTCC_AS_DLL -o libtcc.dll -shared ../libtcc.c
- @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -o tmp-tcc.exe ../tcc.c && mv tmp-tcc.exe i386-win32-tcc.exe
- @./tcc -O2 -B. -m$(TARGET) -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -o tmp-tcc.exe ../tcc.c && mv tmp-tcc.exe x86_64-win32-tcc.exe
-
-PHONY += rebuild
-
-test:
- @(cd ../tests; $(MAKE) -k TCC=$(PWD)/tcc hello-exe hello-run)
- @(cd ../tests; $(MAKE) -k TCC=$(PWD)/tcc vla_test-run tests2-dir pp-dir)
-ifeq ($(CPU), 64)
- @(cd ../tests; $(MAKE) -k TCC=$(PWD)/i386-win32-tcc hello-exe hello-run)
- @(cd ../tests; $(MAKE) -k TCC=$(PWD)/i386-win32-tcc vla_test-run tests2-dir pp-dir)
-endif
-
-PHONY += test
-
-TARNAME = tcc-$(VERSION)-$(ARCH)-win32
-
-tarball:
- @rm -r -f $(TARNAME)
- @mkdir $(TARNAME)
- @cp -r doc $(TARNAME)
- @cp -r examples $(TARNAME)
- @cp -r include $(TARNAME)
- @cp -r lib $(TARNAME)
- @cp -r libtcc $(TARNAME)
- @cp -r build-tcc.bat $(TARNAME)
- @cp -r i386-win32-tcc.exe $(TARNAME)
- @cp -r libtcc.def $(TARNAME)
- @cp -r libtcc.dll $(TARNAME)
- @cp -r Makefile $(TARNAME)
- @cp -r tcc.exe $(TARNAME)
- @cp -r tcc-win32.txt $(TARNAME)
- @cp -r x86_64-win32-tcc.exe $(TARNAME)
- @tar czf $(TARNAME).tar.gz $(TARNAME)
- @rm -r -f $(TARNAME)
-
-PHONY += tarball
-
-clean:
- rm -f *.o *.exe *.dll lib/*.a *.pdb *.obj *.exp *.def *.lib
diff --git a/win32/build-tcc.bat b/win32/build-tcc.bat
index 3c3a726..ceb4411 100644
--- a/win32/build-tcc.bat
+++ b/win32/build-tcc.bat
@@ -4,13 +4,31 @@
@echo off
setlocal
-
-set CC=gcc -Os -s -static
+if (%1)==(-clean) goto :cleanup
+set CC=gcc
set /p VERSION= < ..\VERSION
set INST=
+set BIN=
set DOC=no
+set EXES_ONLY=no
goto :a0
-
+:a2
+shift
+:a3
+shift
+:a0
+if not (%1)==(-c) goto :a1
+set CC=%~2
+if (%2)==(cl) set CC=@call :cl
+goto :a2
+:a1
+if (%1)==(-t) set T=%2&& goto :a2
+if (%1)==(-v) set VERSION=%~2&& goto :a2
+if (%1)==(-i) set INST=%2&& goto :a2
+if (%1)==(-b) set BIN=%2&& goto :a2
+if (%1)==(-d) set DOC=yes&& goto :a3
+if (%1)==(-x) set EXES_ONLY=yes&& goto :a3
+if (%1)==() goto :p1
:usage
echo usage: build-tcc.bat [ options ... ]
echo options:
@@ -18,10 +36,35 @@ echo -c prog use prog (gcc/tcc/cl) to compile tcc
echo -c "prog options" use prog with options to compile tcc
echo -t 32/64 force 32/64 bit default target
echo -v "version" set tcc version
-echo -i dir install tcc into dir
+echo -i tccdir install tcc into tccdir
+echo -b bindir optionally install binaries into bindir elsewhere
echo -d create tcc-doc.html too (needs makeinfo)
+echo -x just create the executables
+echo -clean delete all previously produced files and directories
exit /B 1
+@rem ------------------------------------------------------
+@rem sub-routines
+
+:cleanup
+set LOG=echo
+%LOG% removing files:
+for %%f in (*tcc.exe libtcc.dll lib\*.a) do call :del_file %%f
+for %%f in (..\config.h ..\config.texi) do call :del_file %%f
+for %%f in (include\*.h) do @if exist ..\%%f call :del_file %%f
+for %%f in (include\tcclib.h examples\libtcc_test.c) do call :del_file %%f
+for %%f in (*.o *.obj *.def *.pdb *.lib *.exp *.ilk) do call :del_file %%f
+%LOG% removing directories:
+for %%f in (doc libtcc) do call :del_dir %%f
+%LOG% done.
+exit /B 0
+:del_file
+if exist %1 del %1 && %LOG% %1
+exit /B 0
+:del_dir
+if exist %1 rmdir /Q/S %1 && %LOG% %1
+exit /B 0
+
:cl
@echo off
set CMD=cl
@@ -37,52 +80,16 @@ echo on
%CMD% -O1 -W2 -Zi -MT -GS- -nologo -link -opt:ref,icf
@exit /B %ERRORLEVEL%
-:a2
-shift
-:a1
-shift
-:a0
-if not (%1)==(-c) goto :a3
-set CC=%~2
-if (%2)==(cl) set CC=@call :cl
-goto :a2
-:a3
-if not (%1)==(-t) goto :a4
-set T=%2
-goto :a2
-:a4
-if not (%1)==(-v) goto :a5
-set VERSION=%~2
-goto :a2
-:a5
-if not (%1)==(-i) goto :a6
-set INST=%2
-goto :a2
-:a6
-if not (%1)==(-d) goto :a7
-set DOC=yes
-goto :a1
-:a7
-if not (%1)==() goto :usage
+@rem ------------------------------------------------------
+@rem main program
-if not "%CC%"=="@call :cl" goto :p1
-set VSCOMNTOOLS=%VS150COMNTOOLS%
-if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS140COMNTOOLS%
-if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS130COMNTOOLS%
-if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS120COMNTOOLS%
-if %T%_==32_ set CLVARS="%VSCOMNTOOLS%..\..\VC\bin\vcvars32.bat"
-if %T%_==64_ set CLVARS="%VSCOMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
-if %T%_==_ set T=32& if %Platform%_==X64_ set T=64
-if %CLVARS%_==_ goto :p1
-if exist %CLVARS% call %CLVARS%
:p1
-
if not %T%_==_ goto :p2
set T=32
if %PROCESSOR_ARCHITECTURE%_==AMD64_ set T=64
if %PROCESSOR_ARCHITEW6432%_==AMD64_ set T=64
:p2
-
+if "%CC:~-3%"=="gcc" set CC=%CC% -Os -s -static
set D32=-DTCC_TARGET_PE -DTCC_TARGET_I386
set D64=-DTCC_TARGET_PE -DTCC_TARGET_X86_64
set P32=i386-win32
@@ -91,13 +98,14 @@ if %T%==64 goto :t64
set D=%D32%
set DX=%D64%
set PX=%P64%
-goto :t96
+goto :p3
:t64
set D=%D64%
set DX=%D32%
set PX=%P32%
-:t96
+goto :p3
+:p3
@echo on
:config.h
@@ -116,7 +124,7 @@ for %%f in (*tcc.exe *tcc.dll) do @del %%f
%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0"
%CC% -o %PX%-tcc.exe ..\tcc.c %DX%
-@if (%TCC_FILES%)==(no) goto :files-done
+@if (%EXES_ONLY%)==(yes) goto :files-done
if not exist libtcc mkdir libtcc
if not exist doc mkdir doc
@@ -170,8 +178,11 @@ for %%f in (*.o *.def) do @del %%f
:copy-install
@if (%INST%)==() goto :the_end
if not exist %INST% mkdir %INST%
+@if (%BIN%)==() set BIN=%INST%
+if not exist %BIN% mkdir %BIN%
+for %%f in (*tcc.exe *tcc.dll) do @copy>nul %%f %BIN%\%%f
@if not exist %INST%\lib mkdir %INST%\lib
-for %%f in (*tcc.exe *tcc.dll lib\*.a lib\*.def) do @copy>nul %%f %INST%\%%f
+for %%f in (lib\*.a lib\*.def) do @copy>nul %%f %INST%\%%f
for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %INST%\%%f
:the_end
diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c
index 53e5545..0e04fc0 100644
--- a/win32/lib/crt1.c
+++ b/win32/lib/crt1.c
@@ -16,11 +16,6 @@
#define _PC_53 0x00010000 // 53 bits
#define _PC_64 0x00000000 // 64 bits
-typedef struct
-{
- int newmode;
-} _startupinfo;
-
#ifdef _UNICODE
#define __tgetmainargs __wgetmainargs
#define _tstart _wstart
@@ -33,6 +28,7 @@ typedef struct
#define _runtmain _runmain
#endif
+typedef struct { int newmode; } _startupinfo;
int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
void __cdecl __set_app_type(int apptype);
unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask);
@@ -44,23 +40,19 @@ int _dowildcard;
void _tstart(void)
{
__TRY__
- int ret;
- _startupinfo start_info;
+ _startupinfo start_info = {0};
// Sets the current application type
__set_app_type(_CONSOLE_APP);
// Set default FP precision to 53 bits (8-byte double)
- // _MCW_PC (Precision control) is not supported on
- // the ARM and x64 architectures
-#ifdef __i386
+ // _MCW_PC (Precision control) is not supported on ARM
+#if defined __i386__ || defined __x86_64__
_controlfp(_PC_53, _MCW_PC);
#endif
- start_info.newmode = 0;
__tgetmainargs( &__argc, &__targv, &_tenviron, _dowildcard, &start_info);
- ret = _tmain(__argc, __targv, _tenviron);
- exit(ret);
+ exit(_tmain(__argc, __targv, _tenviron));
}
int _runtmain(int argc, /* as tcc passed in */ char **argv)
@@ -78,8 +70,7 @@ int _runtmain(int argc, /* as tcc passed in */ char **argv)
__argc = argc;
__targv = argv;
#endif
-
-#ifdef __i386
+#if defined __i386__ || defined __x86_64__
_controlfp(_PC_53, _MCW_PC);
#endif
return _tmain(__argc, __targv, _tenviron);
diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c
index 83e2f74..ce3a63f 100644
--- a/win32/lib/wincrt1.c
+++ b/win32/lib/wincrt1.c
@@ -23,71 +23,53 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
#define _runtwinmain _runwinmain
#endif
-typedef struct
-{
- int newmode;
-} _startupinfo; // CLI Vs GUI
-
+typedef struct { int newmode; } _startupinfo;
int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
-int _twinstart(void)
+static int go_winmain(TCHAR *arg1)
{
- __TRY__
+ STARTUPINFO si;
_TCHAR *szCmd, *p;
- STARTUPINFO startinfo;
- _startupinfo start_info_con = {0};
int fShow;
- int ret;
-
- __set_app_type(__GUI_APP);
- _controlfp(0x10000, 0x30000);
- start_info_con.newmode = 0;
- __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con);
+ GetStartupInfo(&si);
+ if (si.dwFlags & STARTF_USESHOWWINDOW)
+ fShow = si.wShowWindow;
+ else
+ fShow = SW_SHOWDEFAULT;
- p = GetCommandLine();
- if (__argc > 1)
- szCmd = _tcsstr(p, __targv[1]);
+ szCmd = NULL, p = GetCommandLine();
+ if (arg1)
+ szCmd = _tcsstr(p, arg1);
if (NULL == szCmd)
- szCmd = __T("");
- else if (szCmd > p && szCmd[-1] == __T('\"'))
+ szCmd = _tcsdup(__T(""));
+ else if (szCmd > p && szCmd[-1] == __T('"'))
--szCmd;
+#if defined __i386__ || defined __x86_64__
+ _controlfp(0x10000, 0x30000);
+#endif
+ return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
+}
- GetStartupInfo(&startinfo);
- fShow = startinfo.wShowWindow;
- if (0 == (startinfo.dwFlags & STARTF_USESHOWWINDOW))
- fShow = SW_SHOWDEFAULT;
-
- ret = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
- exit(ret);
+int _twinstart(void)
+{
+ __TRY__
+ _startupinfo start_info_con = {0};
+ __set_app_type(__GUI_APP);
+ __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con);
+ exit(go_winmain(__argc > 1 ? __targv[1] : NULL));
}
int _runtwinmain(int argc, /* as tcc passed in */ char **argv)
{
- _TCHAR *szCmd, *p;
-
#ifdef UNICODE
_startupinfo start_info = {0};
-
__tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info);
/* may be wrong when tcc has received wildcards (*.c) */
- if (argc < __argc) {
- __targv += __argc - argc;
- __argc = argc;
- }
+ if (argc < __argc)
+ __targv += __argc - argc, __argc = argc;
#else
- __argc = argc;
- __targv = argv;
+ __argc = argc, __targv = argv;
#endif
-
- p = GetCommandLine();
- szCmd = NULL;
- if (argc > 1)
- szCmd = _tcsstr(p, __targv[1]);
- if (NULL == szCmd)
- szCmd = __T("");
- else if (szCmd > p && szCmd[-1] == __T('\"'))
- --szCmd;
- _controlfp(0x10000, 0x30000);
- return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT);
+ return go_winmain(__argc > 1 ? __targv[1] : NULL);
}
diff --git a/win32/tcc-win32.txt b/win32/tcc-win32.txt
index 3609684..751a8e0 100644
--- a/win32/tcc-win32.txt
+++ b/win32/tcc-win32.txt
@@ -108,6 +108,8 @@
------------------------
* You can use the MinGW and MSYS tools available at
http://www.mingw.org
+ http://www.mingw-w64.org
+ http://www.msys2.org
Untar the TCC archive and type in the MSYS shell:
./configure [--prefix installpath]
@@ -116,29 +118,22 @@
The default install location is c:\Program Files\tcc
+ Cygwin can be used too with its mingw cross-compiler installed:
+ ./configure --cross-prefix=i686-w64-mingw32-
+ (the prefix may vary)
+
* Alternatively you can compile TCC with just GCC from MinGW using
> build-tcc.bat (from the win32 directory)
Also MSVC can be used with the "VSTools Developer Command Prompt":
> build-tcc.bat -c cl
- or with a tcc (needs to be in a different directory)
+ or with an existing tcc (needs to be in a different directory)
> build-tcc.bat -c some-tcc-dir\tcc.exe
Also you can copy/install everything into another directory:
> build-tcc.bat -i <dir>
- * You can also bootstrap a native tcc Windows toolchain with cygwin.
- https://www.cygwin.com/
-
- Install Base, gcc, make
- Launch Cygwin Terminal
- > make
- or to force 32bit executables (including 64bit backend)
- > make TARGET=32
- or to force 64bit executables (including 32bit backend)
- > make TARGET=64
-
Limitations:
------------
- On the object file level, currently TCC supports only the ELF format,