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 1d5e386b0a.

  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
master
grischka 2017-10-11 18:13:43 +02:00
parent faa9744f5d
commit da8c62f75d
30 changed files with 433 additions and 663 deletions

113
Makefile
View File

@ -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.def : libtcc.dll tcc$(EXESUF)
./tcc$(EXESUF) -impdef $< -o $@
libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
# import file for windows libtcc.dll
libtcc.def : libtcc.dll tcc$(EXESUF)
$(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)"
# --------------------------------------------------------------------------

68
configure vendored
View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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));

View File

@ -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);

5
tcc.c
View File

@ -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;

35
tcc.h
View File

@ -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
# ifdef TCC_TARGET_PE
# define CONFIG_TCC_TCCINCLUDEPATHS "{B}/include;{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") \
":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
# ifdef TCC_TARGET_PE
# define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi"
# else
# define CONFIG_TCC_SYSINCLUDEPATHS ""
# define CONFIG_TCC_SYSINCLUDEPATHS \
"{B}/include" \
":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
# 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

View File

@ -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;

218
tccelf.c
View File

@ -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,53 +2045,70 @@ 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);
/* 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));
/* 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));
put_dt(dynamic, DT_TEXTREL, 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);
}
build_got_entries(s1);
}
/* we add a section for symbols */
strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
put_elf_str(strsec, "");
/* Allocate strings for section names */
textrel = alloc_sec_names(s1, file_type, strsec);
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 (textrel)
put_dt(dynamic, DT_TEXTREL, 0);
}
if (s1->symbolic)
put_dt(dynamic, DT_SYMBOLIC, 0);
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;
}
/* 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);

View File

@ -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) {

35
tccpe.c
View File

@ -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;

49
tccpp.c
View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -1,3 +1,2 @@
# `modelist' label. Each video mode record looks like:
.text
endtext:

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
};

View File

@ -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

View File

@ -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

View File

@ -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+"

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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*);
static int go_winmain(TCHAR *arg1)
{
STARTUPINFO si;
_TCHAR *szCmd, *p;
int fShow;
GetStartupInfo(&si);
if (si.dwFlags & STARTF_USESHOWWINDOW)
fShow = si.wShowWindow;
else
fShow = SW_SHOWDEFAULT;
szCmd = NULL, p = GetCommandLine();
if (arg1)
szCmd = _tcsstr(p, arg1);
if (NULL == szCmd)
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);
}
int _twinstart(void)
{
__TRY__
_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);
p = GetCommandLine();
if (__argc > 1)
szCmd = _tcsstr(p, __targv[1]);
if (NULL == szCmd)
szCmd = __T("");
else if (szCmd > p && szCmd[-1] == __T('\"'))
--szCmd;
GetStartupInfo(&startinfo);
fShow = startinfo.wShowWindow;
if (0 == (startinfo.dwFlags & STARTF_USESHOWWINDOW))
fShow = SW_SHOWDEFAULT;
ret = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
exit(ret);
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);
}

View File

@ -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,