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
Unified · Split
| @@ -98,16 +98,17 @@ TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67 · 97 unmodified lines | |||
| 98 | LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince | 98 | LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince |
| 99 | 99 | ||
| 100 | PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF)) | 100 | PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF)) |
| 101 | LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),libtcc1-$X.a) | 101 | LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a) |
| 102 | 102 | ||
| 103 | # build cross compilers & libs | 103 | # build cross compilers & libs |
| 104 | cross: $(LIBTCC1_CROSS) $(PROGS_CROSS) | 104 | cross: $(LIBTCC1_CROSS) $(PROGS_CROSS) |
| 105 | 105 | ||
| 106 | # build specific cross compiler & lib | 106 | # build specific cross compiler & lib |
| 107 | cross-%: %-tcc$(EXESUF) libtcc1-%.a ; | 107 | cross-%: %-tcc$(EXESUF) %-libtcc1.a ; |
| 108 | 108 | ||
| 109 | install: install$(CFGWIN) | 109 | install: ; @$(MAKE) --no-print-directory install$(CFGWIN) |
| 110 | uninstall: uninstall$(CFGWIN) | 110 | install-strip: ; @$(MAKE) --no-print-directory install$(CFGWIN) CONFIG_strip=yes |
| 111 | uninstall: ; @$(MAKE) --no-print-directory uninstall$(CFGWIN) | ||
| 111 | 112 | ||
| 112 | ifdef CONFIG_cross | 113 | ifdef CONFIG_cross |
| 113 | all : cross | 114 | all : cross |
| @@ -143,10 +144,10 @@ DEFINES += $(DEF-$(or $(findstring win,$T),unx)) · 29 unmodified lines | |||
| 143 | 144 | ||
| 144 | ifneq ($(X),) | 145 | ifneq ($(X),) |
| 145 | ifeq ($(CONFIG_WIN32),yes) | 146 | ifeq ($(CONFIG_WIN32),yes) |
| 146 | DEF-win += -DTCC_LIBTCC1="\"libtcc1-$T.a\"" | 147 | DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\"" |
| 147 | DEF-unx += -DTCC_LIBTCC1="\"lib/libtcc1-$T.a\"" | 148 | DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\"" |
| 148 | else | 149 | else |
| 149 | DEF-all += -DTCC_LIBTCC1="\"libtcc1-$T.a\"" | 150 | DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\"" |
| 150 | DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" | 151 | DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" |
| 151 | endif | 152 | endif |
| 152 | endif | 153 | endif |
| @@ -217,21 +218,22 @@ libtcc.so: LDFLAGS+=-fPIC · 64 unmodified lines | |||
| 217 | # windows dynamic libtcc library | 218 | # windows dynamic libtcc library |
| 218 | libtcc.dll : $(LIBTCC_OBJ) | 219 | libtcc.dll : $(LIBTCC_OBJ) |
| 219 | $(CC) -shared -o $@ $^ $(LDFLAGS) | 220 | $(CC) -shared -o $@ $^ $(LDFLAGS) |
| 221 | libtcc.dll : DEFINES += -DLIBTCC_AS_DLL | ||
| 220 | 222 | ||
| 223 | # import file for windows libtcc.dll | ||
| 221 | libtcc.def : libtcc.dll tcc$(EXESUF) | 224 | libtcc.def : libtcc.dll tcc$(EXESUF) |
| 222 | ./tcc$(EXESUF) -impdef $< -o $@ | 225 | $(XTCC) -impdef $< -o $@ |
| 223 | 226 | XTCC ?= ./tcc$(EXESUF) | |
| 224 | libtcc.dll : DEFINES += -DLIBTCC_AS_DLL | ||
| 225 | 227 | ||
| 226 | # TinyCC runtime libraries | 228 | # TinyCC runtime libraries |
| 227 | libtcc1.a : tcc$(EXESUF) FORCE | 229 | libtcc1.a : tcc$(EXESUF) FORCE |
| 228 | @$(MAKE) -C lib DEFINES="$(DEF-$T)" | 230 | @$(MAKE) -C lib DEFINES='$(DEF-$T)' |
| 229 | 231 | ||
| 230 | # Cross libtcc1.a | 232 | # Cross libtcc1.a |
| 231 | libtcc1-%.a : %-tcc$(EXESUF) FORCE | 233 | %-libtcc1.a : %-tcc$(EXESUF) FORCE |
| 232 | @$(MAKE) -C lib DEFINES="$(DEF-$*)" CROSS_TARGET=$* | 234 | @$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$* |
| 233 | 235 | ||
| 234 | .PRECIOUS: libtcc1-%.a | 236 | .PRECIOUS: %-libtcc1.a |
| 235 | FORCE: | 237 | FORCE: |
| 236 | 238 | ||
| 237 | # -------------------------------------------------------------------------- | 239 | # -------------------------------------------------------------------------- |
| @@ -252,35 +254,29 @@ tcc-doc.info: tcc-doc.texi · 14 unmodified lines | |||
| 252 | INSTALL = install -m644 | 254 | INSTALL = install -m644 |
| 253 | INSTALLBIN = install -m755 $(STRIP_$(CONFIG_strip)) | 255 | INSTALLBIN = install -m755 $(STRIP_$(CONFIG_strip)) |
| 254 | STRIP_yes = -s | 256 | STRIP_yes = -s |
| 255 | install-strip: install | ||
| 256 | install-strip: CONFIG_strip = yes | ||
| 257 | 257 | ||
| 258 | TRY-INSTALL = $(if $(wildcard $1),mkdir -p $2 && $(INSTALL) $1 $2) | 258 | LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS)) |
| 259 | LIBTCC1_W = $(wildcard $(filter %-win32.a %-wince.a,$(LIBTCC1_CROSS))) | 259 | LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS)) |
| 260 | LIBTCC1_U = $(wildcard $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))) | 260 | IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2) |
| 261 | PROGS_X = $(wildcard $(PROGS_CROSS)) | 261 | IBw = $(call IB,$(wildcard $1),$2) |
| 262 | IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2) | ||
| 263 | IFw = $(call IF,$(wildcard $1),$2) | ||
| 264 | IR = mkdir -p $2 && cp -r $1/. $2 | ||
| 262 | 265 | ||
| 263 | # install progs & libs | 266 | # install progs & libs |
| 264 | install-unx: | 267 | install-unx: |
| 265 | mkdir -p "$(bindir)" | 268 | $(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)") |
| 266 | $(INSTALLBIN) $(PROGS) $(PROGS_X) "$(bindir)" | 269 | $(call IFw,$(LIBTCC1) $(LIBTCC1_U),"$(tccdir)") |
| 267 | mkdir -p "$(tccdir)" | 270 | $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include") |
| 268 | $(INSTALL) $(LIBTCC1) $(LIBTCC1_U) "$(tccdir)" | 271 | $(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)") |
| 269 | mkdir -p "$(tccdir)/include" | 272 | $(call IF,$(TOPSRC)/libtcc.h,"$(includedir)") |
| 270 | $(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/include" | 273 | $(call IFw,tcc.1,"$(mandir)/man1") |
| 271 | mkdir -p "$(libdir)" | 274 | $(call IFw,tcc-doc.info,"$(infodir)") |
| 272 | $(INSTALL) $(LIBTCC) "$(libdir)" | 275 | $(call IFw,tcc-doc.html,"$(docdir)") |
| 273 | mkdir -p "$(includedir)" | 276 | ifneq "$(wildcard $(LIBTCC1_W))" "" |
| 274 | $(INSTALL) $(TOPSRC)/libtcc.h "$(includedir)" | 277 | $(call IFw,$(TOPSRC)/win32/lib/*.def $(LIBTCC1_W),"$(tccdir)/win32/lib") |
| 275 | $(call TRY-INSTALL,tcc.1,"$(mandir)/man1") | 278 | $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/win32/include") |
| 276 | $(call TRY-INSTALL,tcc-doc.info,"$(infodir)") | 279 | $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/win32/include") |
| 277 | $(call TRY-INSTALL,tcc-doc.html,"$(docdir)") | ||
| 278 | ifneq "$(LIBTCC1_W)" "" | ||
| 279 | mkdir -p "$(tccdir)/win32/lib" | ||
| 280 | $(INSTALL) $(TOPSRC)/win32/lib/*.def $(LIBTCC1_W) "$(tccdir)/win32/lib" | ||
| 281 | mkdir -p "$(tccdir)/win32/include" | ||
| 282 | cp -r $(TOPSRC)/win32/include/. "$(tccdir)/win32/include" | ||
| 283 | $(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/win32/include" | ||
| 284 | endif | 280 | endif |
| 285 | 281 | ||
| 286 | # uninstall | 282 | # uninstall |
| @@ -293,32 +289,31 @@ uninstall-unx: · 6 unmodified lines | |||
| 293 | 289 | ||
| 294 | # install progs & libs on windows | 290 | # install progs & libs on windows |
| 295 | install-win: | 291 | install-win: |
| 296 | mkdir -p "$(tccdir)" | 292 | $(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)") |
| 297 | $(INSTALL) $(PROGS) $(subst libtcc.a,,$(LIBTCC)) $(PROGS_X) "$(tccdir)" | 293 | $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib") |
| 298 | mkdir -p "$(tccdir)/lib" | 294 | $(call IFw,libtcc1.a $(LIBTCC1_W),"$(tccdir)/lib") |
| 299 | $(INSTALL) $(TOPSRC)/win32/lib/*.def "$(tccdir)/lib" | 295 | $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include") |
| 300 | $(INSTALL) libtcc1.a $(LIBTCC1_W) "$(tccdir)/lib" | 296 | $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include") |
| 301 | mkdir -p "$(tccdir)/include" | 297 | $(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples") |
| 302 | cp -r $(TOPSRC)/win32/include/. "$(tccdir)/include" | 298 | $(call IF,$(TOPSRC)/tests/libtcc_test.c,"$(tccdir)/examples") |
| 303 | $(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/include" | 299 | $(call IFw,$(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)),"$(libdir)") |
| 304 | mkdir -p "$(tccdir)/examples" | 300 | $(call IFw,$(TOPSRC)/win32/tcc-win32.txt tcc-doc.html,"$(docdir)") |
| 305 | cp -r $(TOPSRC)/win32/examples/. "$(tccdir)/examples" | 301 | ifneq "$(wildcard $(LIBTCC1_U))" "" |
| 306 | $(INSTALL) $(TOPSRC)/tests/libtcc_test.c "$(tccdir)/examples" | 302 | $(call IFw,$(LIBTCC1_U),"$(tccdir)/lib") |
| 307 | mkdir -p "$(tccdir)/libtcc" | 303 | $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/lib/include") |
| 308 | $(INSTALL) $(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)) "$(tccdir)/libtcc" | ||
| 309 | mkdir -p "$(tccdir)/doc" | ||
| 310 | $(INSTALL) $(TOPSRC)/win32/tcc-win32.txt $(wildcard tcc-doc.html) "$(tccdir)/doc" | ||
| 311 | ifneq "$(LIBTCC1_U)" "" | ||
| 312 | $(INSTALL) $(LIBTCC1_U) "$(tccdir)/lib" | ||
| 313 | mkdir -p "$(tccdir)/lib/include"; | ||
| 314 | $(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/lib/include" | ||
| 315 | endif | 304 | endif |
| 316 | 305 | ||
| 317 | # the msys-git shell works to configure && make except it does not have install | 306 | # the msys-git shell works to configure && make except it does not have install |
| 307 | ifeq ($(CONFIG_WIN32)-$(shell which install >/dev/null 2>&1 || echo no),yes-no) | ||
| 318 | install-win : INSTALL = cp | 308 | install-win : INSTALL = cp |
| 309 | install-win : INSTALLBIN = cp | ||
| 310 | endif | ||
| 319 | 311 | ||
| 320 | # uninstall on windows | 312 | # uninstall on windows |
| 321 | uninstall-win: | 313 | uninstall-win: |
| 314 | @rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS) libtcc.dll,"$(bindir)/$P") | ||
| 315 | @rm -fv $(foreach F,tcc-doc.html tcc-win32.txt,"$(docdir)/$F") | ||
| 316 | @rm -fv $(foreach F,libtcc.h libtcc.def libtcc.a,"$(libdir)/$F") | ||
| 322 | rm -r "$(tccdir)" | 317 | rm -r "$(tccdir)" |
| 323 | 318 | ||
| 324 | # -------------------------------------------------------------------------- | 319 | # -------------------------------------------------------------------------- |
| @@ -56,7 +56,6 @@ case $targetos in · 55 unmodified lines | |||
| 56 | DLLSUF=".dylib" | 56 | DLLSUF=".dylib" |
| 57 | ;; | 57 | ;; |
| 58 | MINGW*|MSYS*|CYGWIN*) | 58 | MINGW*|MSYS*|CYGWIN*) |
| 59 | confvars="$confvars WIN32" | ||
| 60 | mingw32=yes | 59 | mingw32=yes |
| 61 | ;; | 60 | ;; |
| 62 | DragonFly|OpenBSD|FreeBSD|NetBSD) | 61 | DragonFly|OpenBSD|FreeBSD|NetBSD) |
| @@ -126,8 +125,6 @@ for opt do · 63 unmodified lines | |||
| 126 | ;; | 125 | ;; |
| 127 | --cpu=*) cpu=`echo $opt | cut -d '=' -f 2` | 126 | --cpu=*) cpu=`echo $opt | cut -d '=' -f 2` |
| 128 | ;; | 127 | ;; |
| 129 | --enable-mingw32) confvars="$confvars WIN32"; mingw32="yes" | ||
| 130 | ;; | ||
| 131 | --enable-cross) confvars="$confvars cross" | 128 | --enable-cross) confvars="$confvars cross" |
| 132 | ;; | 129 | ;; |
| 133 | --disable-static) confvars="$confvars static=no" | 130 | --disable-static) confvars="$confvars static=no" |
| @@ -142,6 +139,8 @@ for opt do · 8 unmodified lines | |||
| 142 | ;; | 139 | ;; |
| 143 | --with-selinux) confvars="$confvars selinux" | 140 | --with-selinux) confvars="$confvars selinux" |
| 144 | ;; | 141 | ;; |
| 142 | --config-mingw32*) mingw32=$(echo "$opt=yes" | cut -d '=' -f 2) | ||
| 143 | ;; | ||
| 145 | --config-*) confvars="$confvars ${opt#--config-}"; suggest="no" | 144 | --config-*) confvars="$confvars ${opt#--config-}"; suggest="no" |
| 146 | ;; | 145 | ;; |
| 147 | --help|-h) show_help="yes" | 146 | --help|-h) show_help="yes" |
| @@ -216,22 +215,12 @@ if test "$mingw32" = "yes" ; then · 68 unmodified lines | |||
| 216 | if test "$cc" = gcc; then | 215 | if test "$cc" = gcc; then |
| 217 | test -z "$LDFLAGS" && LDFLAGS="-static" | 216 | test -z "$LDFLAGS" && LDFLAGS="-static" |
| 218 | fi | 217 | fi |
| 219 | if test x"$tccdir" = x""; then | 218 | test -z "$prefix" && prefix="C:/Program Files/tcc" |
| 220 | tccdir="tcc" | 219 | test -z "$tccdir" && tccdir="${prefix}" |
| 221 | fi | 220 | test -z "$bindir" && bindir="${tccdir}" |
| 222 | if test -z "$prefix" ; then | 221 | test -z "$docdir" && docdir="${tccdir}/doc" |
| 223 | prefix="C:/Program Files/${tccdir}" | 222 | test -z "$libdir" && libdir="${tccdir}/libtcc" |
| 224 | fi | 223 | confvars="$confvars WIN32" |
| 225 | if test -z "$sharedir" ; then | ||
| 226 | sharedir="${prefix}" | ||
| 227 | fi | ||
| 228 | execprefix="$prefix" | ||
| 229 | bindir="${prefix}" | ||
| 230 | tccdir="${prefix}" | ||
| 231 | libdir="${prefix}/lib" | ||
| 232 | docdir="${sharedir}/doc" | ||
| 233 | mandir="${sharedir}/man" | ||
| 234 | infodir="${sharedir}/info" | ||
| 235 | LIBSUF=".lib" | 224 | LIBSUF=".lib" |
| 236 | EXESUF=".exe" | 225 | EXESUF=".exe" |
| 237 | DLLSUF=".dll" | 226 | DLLSUF=".dll" |
| @@ -263,12 +252,11 @@ else · 25 unmodified lines | |||
| 263 | if test x"$tccdir" = x""; then | 252 | if test x"$tccdir" = x""; then |
| 264 | tccdir="${libdir}/tcc" | 253 | tccdir="${libdir}/tcc" |
| 265 | fi | 254 | fi |
| 255 | if test x"$includedir" = x""; then | ||
| 256 | includedir="${prefix}/include" | ||
| 257 | fi | ||
| 266 | fi # mingw32 | 258 | fi # mingw32 |
| 267 | 259 | ||
| 268 | if test x"$includedir" = x""; then | ||
| 269 | includedir="${prefix}/include" | ||
| 270 | fi | ||
| 271 | |||
| 272 | if test x"$show_help" = "xyes" ; then | 260 | if test x"$show_help" = "xyes" ; then |
| 273 | cat << EOF | 261 | cat << EOF |
| 274 | Usage: configure [options] | 262 | Usage: configure [options] |
| @@ -302,7 +290,6 @@ Advanced options (experts only): · 27 unmodified lines | |||
| 302 | --enable-static make libtcc.a instead of libtcc.dll (win32) | 290 | --enable-static make libtcc.a instead of libtcc.dll (win32) |
| 303 | --disable-rpath disable use of -rpath with the above | 291 | --disable-rpath disable use of -rpath with the above |
| 304 | --with-libgcc use libgcc_s.so.1 instead of libtcc1.a | 292 | --with-libgcc use libgcc_s.so.1 instead of libtcc1.a |
| 305 | --enable-mingw32 build windows version on linux with mingw32 | ||
| 306 | --enable-cross build cross compilers | 293 | --enable-cross build cross compilers |
| 307 | --with-selinux use mmap for executable memory (with tcc -run) | 294 | --with-selinux use mmap for executable memory (with tcc -run) |
| 308 | --sysincludepaths=... specify system include paths, colon separated | 295 | --sysincludepaths=... specify system include paths, colon separated |
| @@ -310,7 +297,7 @@ Advanced options (experts only): · 1 unmodified line | |||
| 310 | --crtprefix=... specify locations of crt?.o, colon separated | 297 | --crtprefix=... specify locations of crt?.o, colon separated |
| 311 | --elfinterp=... specify elf interpreter | 298 | --elfinterp=... specify elf interpreter |
| 312 | --triplet=... specify system library/include directory triplet | 299 | --triplet=... specify system library/include directory triplet |
| 313 | --config-uClibc,-musl... enable specific configuration for some systems | 300 | --config-uClibc,-musl,-mingw32... enable system specific configurations |
| 314 | EOF | 301 | EOF |
| 315 | #echo "NOTE: The object files are build at the place where configure is launched" | 302 | #echo "NOTE: The object files are build at the place where configure is launched" |
| 316 | exit 1 | 303 | exit 1 |
| @@ -320,15 +307,14 @@ cc="${cross_prefix}${cc}" · 3 unmodified lines | |||
| 320 | ar="${cross_prefix}${ar}" | 307 | ar="${cross_prefix}${ar}" |
| 321 | strip="${cross_prefix}${strip}" | 308 | strip="${cross_prefix}${strip}" |
| 322 | 309 | ||
| 323 | CONFTEST=./conftest$EXESUF | ||
| 324 | if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then | ||
| 325 | echo "configure: error: '$cc' failed to compile conftest.c." | ||
| 326 | else | ||
| 327 | gcc_major="$($CONFTEST version)" | ||
| 328 | gcc_minor="$($CONFTEST minor)" | ||
| 329 | fi | ||
| 330 | |||
| 331 | if test -z "$cross_prefix" ; then | 310 | if test -z "$cross_prefix" ; then |
| 311 | CONFTEST=./conftest$EXESUF | ||
| 312 | if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then | ||
| 313 | echo "configure: error: '$cc' failed to compile conftest.c." | ||
| 314 | else | ||
| 315 | gcc_major="$($CONFTEST version)" | ||
| 316 | gcc_minor="$($CONFTEST minor)" | ||
| 317 | fi | ||
| 332 | bigendian="$($CONFTEST bigendian)" | 318 | bigendian="$($CONFTEST bigendian)" |
| 333 | if test "$mingw32" = "no" ; then | 319 | if test "$mingw32" = "no" ; then |
| 334 | 320 | ||
| @@ -401,13 +387,13 @@ fi · 66 unmodified lines | |||
| 401 | 387 | ||
| 402 | fcho() { if test -n "$2"; then echo "$1$2"; fi } | 388 | fcho() { if test -n "$2"; then echo "$1$2"; fi } |
| 403 | 389 | ||
| 404 | echo "Binary directory $bindir" | 390 | fcho "Binary directory " "$bindir" |
| 405 | echo "TinyCC directory $tccdir" | 391 | fcho "TinyCC directory " "$tccdir" |
| 406 | echo "Library directory $libdir" | 392 | fcho "Library directory " "$libdir" |
| 407 | echo "Include directory $includedir" | 393 | fcho "Include directory " "$includedir" |
| 408 | echo "Manual directory $mandir" | 394 | fcho "Manual directory " "$mandir" |
| 409 | echo "Info directory $infodir" | 395 | fcho "Info directory " "$infodir" |
| 410 | echo "Doc directory $docdir" | 396 | fcho "Doc directory " "$docdir" |
| 411 | fcho "Target root prefix " "$sysroot" | 397 | fcho "Target root prefix " "$sysroot" |
| 412 | echo "Source path $source_path" | 398 | echo "Source path $source_path" |
| 413 | echo "C compiler $cc ($gcc_major.$gcc_minor)" | 399 | echo "C compiler $cc ($gcc_major.$gcc_minor)" |
| @@ -471,8 +457,6 @@ print_mak CONFIG_LDDIR "$tcc_lddir" · 57 unmodified lines | |||
| 471 | print_mak CONFIG_TRIPLET "$triplet" | 457 | print_mak CONFIG_TRIPLET "$triplet" |
| 472 | print_mak_int TCC_CPU_VERSION "$cpuver" | 458 | print_mak_int TCC_CPU_VERSION "$cpuver" |
| 473 | 459 | ||
| 474 | echo "#define GCC_MAJOR $gcc_major" >> $TMPH | ||
| 475 | echo "#define GCC_MINOR $gcc_minor" >> $TMPH | ||
| 476 | if test "$cpu" = "aarch64" ; then | 460 | if test "$cpu" = "aarch64" ; then |
| 477 | echo "ARCH=arm64" >> config.mak | 461 | echo "ARCH=arm64" >> config.mak |
| 478 | else | 462 | else |
| @@ -16,12 +16,7 @@ typedef struct { · 15 unmodified lines | |||
| 16 | char *reg_save_area; | 16 | char *reg_save_area; |
| 17 | } __va_list_struct; | 17 | } __va_list_struct; |
| 18 | 18 | ||
| 19 | /* Avoid conflicting definition for va_list on musl libc */ | ||
| 20 | #if !defined __DEFINED_va_list || defined __TCC_NEEDS_va_list | ||
| 21 | typedef __va_list_struct va_list[1]; | 19 | typedef __va_list_struct va_list[1]; |
| 22 | #undef __DEFINED_va_list | ||
| 23 | #define __DEFINED_va_list | ||
| 24 | #endif | ||
| 25 | 20 | ||
| 26 | void __va_start(__va_list_struct *ap, void *fp); | 21 | void __va_start(__va_list_struct *ap, void *fp); |
| 27 | void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align); | 22 | void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align); |
| @@ -7,20 +7,20 @@ include $(TOP)/Makefile · 6 unmodified lines | |||
| 7 | VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib | 7 | VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib |
| 8 | T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown) | 8 | T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown) |
| 9 | X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-) | 9 | X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-) |
| 10 | BIN = $(TOP)/libtcc1$(if $(CROSS_TARGET),-$(CROSS_TARGET)).a | 10 | BIN = $(TOP)/$(X)libtcc1.a |
| 11 | 11 | ||
| 12 | TCC = $(TOP)/$(X)tcc$(EXESUF) | 12 | XTCC ?= $(TOP)/$(X)tcc$(EXESUF) |
| 13 | XCC = $(TCC) | 13 | XCC = $(XTCC) |
| 14 | XAR = $(TCC) -ar | 14 | XAR = $(XTCC) -ar |
| 15 | XFLAGS-unx = -B$(TOPSRC) | 15 | XFLAGS-unx = -B$(TOPSRC) |
| 16 | XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include | 16 | XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include |
| 17 | XFLAGS = $(XFLAGS$(XCFG)) | 17 | XFLAGS = $(XFLAGS$(XCFG)) |
| 18 | XCFG = $(or $(findstring -win,$T),-unx) | 18 | XCFG = $(or $(findstring -win,$T),-unx) |
| 19 | 19 | ||
| 20 | # in order to use gcc, tyoe: make <target>lib-usegcc=yes | 20 | # in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes |
| 21 | armlib-usegcc ?= no | 21 | arm-libtcc1-usegcc ?= no |
| 22 | 22 | ||
| 23 | ifeq "$($(X)$(T)lib-usegcc)" "yes" | 23 | ifeq "$($(T)-libtcc1-usegcc)" "yes" |
| 24 | XCC = $(CC) | 24 | XCC = $(CC) |
| 25 | XAR = $(AR) | 25 | XAR = $(AR) |
| 26 | XFLAGS = $(CFLAGS) -fPIC | 26 | XFLAGS = $(CFLAGS) -fPIC |
| @@ -104,10 +104,8 @@ static void tcc_set_lib_path_w32(TCCState *s) · 103 unmodified lines | |||
| 104 | char path[1024], *p; | 104 | char path[1024], *p; |
| 105 | GetModuleFileNameA(tcc_module, path, sizeof path); | 105 | GetModuleFileNameA(tcc_module, path, sizeof path); |
| 106 | p = tcc_basename(normalize_slashes(strlwr(path))); | 106 | p = tcc_basename(normalize_slashes(strlwr(path))); |
| 107 | if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5)) | 107 | if (p > path) |
| 108 | p -= 5; | 108 | --p; |
| 109 | else if (p > path) | ||
| 110 | p--; | ||
| 111 | *p = 0; | 109 | *p = 0; |
| 112 | tcc_set_lib_path(s, path); | 110 | tcc_set_lib_path(s, path); |
| 113 | } | 111 | } |
| @@ -440,7 +438,7 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char * · 326 unmodified lines | |||
| 440 | CString str; | 438 | CString str; |
| 441 | 439 | ||
| 442 | cstr_new(&str); | 440 | cstr_new(&str); |
| 443 | for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) { | 441 | for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) { |
| 444 | if (c == '{' && p[1] && p[2] == '}') { | 442 | if (c == '{' && p[1] && p[2] == '}') { |
| 445 | c = p[1], p += 2; | 443 | c = p[1], p += 2; |
| 446 | if (c == 'B') | 444 | if (c == 'B') |
| @@ -804,6 +802,8 @@ LIBTCCAPI TCCState *tcc_new(void) · 357 unmodified lines | |||
| 804 | #endif | 802 | #endif |
| 805 | #elif defined(TCC_TARGET_ARM64) | 803 | #elif defined(TCC_TARGET_ARM64) |
| 806 | tcc_define_symbol(s, "__aarch64__", NULL); | 804 | tcc_define_symbol(s, "__aarch64__", NULL); |
| 805 | #elif defined TCC_TARGET_C67 | ||
| 806 | tcc_define_symbol(s, "__C67__", NULL); | ||
| 807 | #endif | 807 | #endif |
| 808 | 808 | ||
| 809 | #ifdef TCC_TARGET_PE | 809 | #ifdef TCC_TARGET_PE |
| @@ -827,13 +827,13 @@ LIBTCCAPI TCCState *tcc_new(void) · 17 unmodified lines | |||
| 827 | # if defined(__FreeBSD_kernel__) | 827 | # if defined(__FreeBSD_kernel__) |
| 828 | tcc_define_symbol(s, "__FreeBSD_kernel__", NULL); | 828 | tcc_define_symbol(s, "__FreeBSD_kernel__", NULL); |
| 829 | # endif | 829 | # endif |
| 830 | #endif | ||
| 831 | # if defined(__NetBSD__) | 830 | # if defined(__NetBSD__) |
| 832 | tcc_define_symbol(s, "__NetBSD__", "__NetBSD__"); | 831 | tcc_define_symbol(s, "__NetBSD__", "__NetBSD__"); |
| 833 | # endif | 832 | # endif |
| 834 | # if defined(__OpenBSD__) | 833 | # if defined(__OpenBSD__) |
| 835 | tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__"); | 834 | tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__"); |
| 836 | # endif | 835 | # endif |
| 836 | #endif | ||
| 837 | 837 | ||
| 838 | /* TinyCC & gcc defines */ | 838 | /* TinyCC & gcc defines */ |
| 839 | #if PTR_SIZE == 4 | 839 | #if PTR_SIZE == 4 |
| @@ -853,14 +853,6 @@ LIBTCCAPI TCCState *tcc_new(void) · 13 unmodified lines | |||
| 853 | tcc_define_symbol(s, "__LP64__", NULL); | 853 | tcc_define_symbol(s, "__LP64__", NULL); |
| 854 | #endif | 854 | #endif |
| 855 | 855 | ||
| 856 | #if defined(TCC_MUSL) | ||
| 857 | tcc_define_symbol(s, "__TCC_NEEDS_va_list", ""); | ||
| 858 | tcc_define_symbol(s, "__builtin_va_list", "va_list"); | ||
| 859 | tcc_define_symbol(s, "__DEFINED_va_list", ""); | ||
| 860 | tcc_define_symbol(s, "__DEFINED___isoc_va_list", ""); | ||
| 861 | tcc_define_symbol(s, "__isoc_va_list", "void *"); | ||
| 862 | #endif /* TCC_MUSL */ | ||
| 863 | |||
| 864 | #ifdef TCC_TARGET_PE | 856 | #ifdef TCC_TARGET_PE |
| 865 | tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short"); | 857 | tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short"); |
| 866 | tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short"); | 858 | tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short"); |
| @@ -887,6 +879,11 @@ LIBTCCAPI TCCState *tcc_new(void) · 20 unmodified lines | |||
| 887 | tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", | 879 | tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", |
| 888 | "name proto __asm__ (#alias) __THROW"); | 880 | "name proto __asm__ (#alias) __THROW"); |
| 889 | # endif | 881 | # endif |
| 882 | # if defined(TCC_MUSL) | ||
| 883 | tcc_define_symbol(s, "__DEFINED_va_list", ""); | ||
| 884 | tcc_define_symbol(s, "__DEFINED___isoc_va_list", ""); | ||
| 885 | tcc_define_symbol(s, "__isoc_va_list", "void *"); | ||
| 886 | # endif /* TCC_MUSL */ | ||
| 890 | /* Some GCC builtins that are simple to express as macros. */ | 887 | /* Some GCC builtins that are simple to express as macros. */ |
| 891 | tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x"); | 888 | tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x"); |
| 892 | #endif /* ndef TCC_TARGET_PE */ | 889 | #endif /* ndef TCC_TARGET_PE */ |
| @@ -906,7 +903,6 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 13 unmodified lines | |||
| 906 | 903 | ||
| 907 | /* free include paths */ | 904 | /* free include paths */ |
| 908 | dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes); | 905 | dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes); |
| 909 | dynarray_reset(&s1->tccinclude_paths, &s1->nb_tccinclude_paths); | ||
| 910 | dynarray_reset(&s1->include_paths, &s1->nb_include_paths); | 906 | dynarray_reset(&s1->include_paths, &s1->nb_include_paths); |
| 911 | dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths); | 907 | dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths); |
| 912 | dynarray_reset(&s1->cmd_include_files, &s1->nb_cmd_include_files); | 908 | 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) · 34 unmodified lines | |||
| 947 | if (!s->nostdinc) { | 943 | if (!s->nostdinc) { |
| 948 | /* default include paths */ | 944 | /* default include paths */ |
| 949 | /* -isystem paths have already been handled */ | 945 | /* -isystem paths have already been handled */ |
| 950 | tcc_add_tccinclude_path(s, CONFIG_TCC_TCCINCLUDEPATHS); | ||
| 951 | tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS); | 946 | tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS); |
| 952 | } | 947 | } |
| 953 | 948 | ||
| @@ -985,12 +980,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 31 unmodified lines | |||
| 985 | return 0; | 980 | return 0; |
| 986 | } | 981 | } |
| 987 | 982 | ||
| 988 | LIBTCCAPI int tcc_add_tccinclude_path(TCCState *s, const char *pathname) | ||
| 989 | { | ||
| 990 | tcc_split_path(s, &s->tccinclude_paths, &s->nb_tccinclude_paths, pathname); | ||
| 991 | return 0; | ||
| 992 | } | ||
| 993 | |||
| 994 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) | 983 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) |
| 995 | { | 984 | { |
| 996 | tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname); | 985 | tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname); |
| @@ -1547,7 +1536,6 @@ static const TCCOption tcc_options[] = { · 550 unmodified lines | |||
| 1547 | { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 1536 | { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1548 | { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 1537 | { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1549 | { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG }, | 1538 | { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG }, |
| 1550 | { "iwithprefix", TCC_OPTION_iwithprefix, TCC_OPTION_HAS_ARG }, | ||
| 1551 | { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG }, | 1539 | { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG }, |
| 1552 | { "nostdinc", TCC_OPTION_nostdinc, 0 }, | 1540 | { "nostdinc", TCC_OPTION_nostdinc, 0 }, |
| 1553 | { "nostdlib", TCC_OPTION_nostdlib, 0 }, | 1541 | { "nostdlib", TCC_OPTION_nostdlib, 0 }, |
| @@ -1682,7 +1670,6 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) · 128 unmodified lines | |||
| 1682 | int last_o = -1; | 1670 | int last_o = -1; |
| 1683 | int x; | 1671 | int x; |
| 1684 | CString linker_arg; /* collect -Wl options */ | 1672 | CString linker_arg; /* collect -Wl options */ |
| 1685 | char buf[1024]; | ||
| 1686 | int tool = 0, arg_start = 0, noaction = optind; | 1673 | int tool = 0, arg_start = 0, noaction = optind; |
| 1687 | char **argv = *pargv; | 1674 | char **argv = *pargv; |
| 1688 | int argc = *pargc; | 1675 | int argc = *pargc; |
| @@ -1827,10 +1814,6 @@ reparse: · 138 unmodified lines | |||
| 1827 | case TCC_OPTION_isystem: | 1814 | case TCC_OPTION_isystem: |
| 1828 | tcc_add_sysinclude_path(s, optarg); | 1815 | tcc_add_sysinclude_path(s, optarg); |
| 1829 | break; | 1816 | break; |
| 1830 | case TCC_OPTION_iwithprefix: | ||
| 1831 | snprintf(buf, sizeof buf, "{B}/%s", optarg); | ||
| 1832 | tcc_add_tccinclude_path(s, buf); | ||
| 1833 | break; | ||
| 1834 | case TCC_OPTION_include: | 1817 | case TCC_OPTION_include: |
| 1835 | dynarray_add(&s->cmd_include_files, | 1818 | dynarray_add(&s->cmd_include_files, |
| 1836 | &s->nb_cmd_include_files, tcc_strdup(optarg)); | 1819 | &s->nb_cmd_include_files, tcc_strdup(optarg)); |
| @@ -32,9 +32,6 @@ LIBTCCAPI void tcc_set_options(TCCState *s, const char *str); · 31 unmodified lines | |||
| 32 | /*****************************/ | 32 | /*****************************/ |
| 33 | /* preprocessor */ | 33 | /* preprocessor */ |
| 34 | 34 | ||
| 35 | /* add in tcc include path, searched before anything else */ | ||
| 36 | LIBTCCAPI int tcc_add_tccinclude_path(TCCState *s, const char *pathname); | ||
| 37 | |||
| 38 | /* add include path */ | 35 | /* add include path */ |
| 39 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname); | 36 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname); |
| 40 | 37 | ||
| @@ -86,7 +86,6 @@ static const char help2[] = · 85 unmodified lines | |||
| 86 | " -Wp,-opt same as -opt\n" | 86 | " -Wp,-opt same as -opt\n" |
| 87 | " -include file include 'file' above each input file\n" | 87 | " -include file include 'file' above each input file\n" |
| 88 | " -isystem dir add 'dir' to system include path\n" | 88 | " -isystem dir add 'dir' to system include path\n" |
| 89 | " -iwithprefix dir set tcc's private include/library subdir\n" | ||
| 90 | " -static link to static libraries (not recommended)\n" | 89 | " -static link to static libraries (not recommended)\n" |
| 91 | " -dumpversion print version\n" | 90 | " -dumpversion print version\n" |
| 92 | " -print-search-dirs print search paths\n" | 91 | " -print-search-dirs print search paths\n" |
| @@ -181,7 +180,6 @@ static void print_search_dirs(TCCState *s) · 88 unmodified lines | |||
| 181 | { | 180 | { |
| 182 | printf("install: %s\n", s->tcc_lib_path); | 181 | printf("install: %s\n", s->tcc_lib_path); |
| 183 | /* print_dirs("programs", NULL, 0); */ | 182 | /* print_dirs("programs", NULL, 0); */ |
| 184 | print_dirs("tcc-include", s->tccinclude_paths, s->nb_tccinclude_paths); | ||
| 185 | print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths); | 183 | print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths); |
| 186 | print_dirs("libraries", s->library_paths, s->nb_library_paths); | 184 | print_dirs("libraries", s->library_paths, s->nb_library_paths); |
| 187 | #ifndef TCC_TARGET_PE | 185 | #ifndef TCC_TARGET_PE |
| @@ -197,7 +195,7 @@ static void set_environment(TCCState *s) · 9 unmodified lines | |||
| 197 | 195 | ||
| 198 | path = getenv("C_INCLUDE_PATH"); | 196 | path = getenv("C_INCLUDE_PATH"); |
| 199 | if(path != NULL) { | 197 | if(path != NULL) { |
| 200 | tcc_add_include_path(s, path); | 198 | tcc_add_sysinclude_path(s, path); |
| 201 | } | 199 | } |
| 202 | path = getenv("CPATH"); | 200 | path = getenv("CPATH"); |
| 203 | if(path != NULL) { | 201 | if(path != NULL) { |
| @@ -278,6 +276,7 @@ redo: · 74 unmodified lines | |||
| 278 | return 0; | 276 | return 0; |
| 279 | if (opt == OPT_PRINT_DIRS) { | 277 | if (opt == OPT_PRINT_DIRS) { |
| 280 | /* initialize search dirs */ | 278 | /* initialize search dirs */ |
| 279 | set_environment(s); | ||
| 281 | tcc_set_output_type(s, TCC_OUTPUT_MEMORY); | 280 | tcc_set_output_type(s, TCC_OUTPUT_MEMORY); |
| 282 | print_search_dirs(s); | 281 | print_search_dirs(s); |
| 283 | return 0; | 282 | return 0; |
| @@ -101,10 +101,12 @@ extern long double strtold (const char *__nptr, char **__endptr); · 100 unmodified lines | |||
| 101 | # define IS_DIRSEP(c) (c == '/' || c == '\\') | 101 | # define IS_DIRSEP(c) (c == '/' || c == '\\') |
| 102 | # define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2]))) | 102 | # define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2]))) |
| 103 | # define PATHCMP stricmp | 103 | # define PATHCMP stricmp |
| 104 | # define PATHSEP ";" | ||
| 104 | #else | 105 | #else |
| 105 | # define IS_DIRSEP(c) (c == '/') | 106 | # define IS_DIRSEP(c) (c == '/') |
| 106 | # define IS_ABSPATH(p) IS_DIRSEP(p[0]) | 107 | # define IS_ABSPATH(p) IS_DIRSEP(p[0]) |
| 107 | # define PATHCMP strcmp | 108 | # define PATHCMP strcmp |
| 109 | # define PATHSEP ":" | ||
| 108 | #endif | 110 | #endif |
| 109 | 111 | ||
| 110 | /* -------------------------------------------- */ | 112 | /* -------------------------------------------- */ |
| @@ -195,21 +197,14 @@ extern long double strtold (const char *__nptr, char **__endptr); · 84 unmodified lines | |||
| 195 | /* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */ | 197 | /* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */ |
| 196 | 198 | ||
| 197 | /* system include paths */ | 199 | /* system include paths */ |
| 198 | #ifndef CONFIG_TCC_TCCINCLUDEPATHS | 200 | #ifndef CONFIG_TCC_SYSINCLUDEPATHS |
| 199 | # ifdef TCC_TARGET_PE | 201 | # ifdef TCC_TARGET_PE |
| 200 | # define CONFIG_TCC_TCCINCLUDEPATHS "{B}/include;{B}/include/winapi" | 202 | # define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi" |
| 201 | # else | 203 | # else |
| 202 | # define CONFIG_TCC_TCCINCLUDEPATHS "{B}/include" | ||
| 203 | # endif | ||
| 204 | #endif | ||
| 205 | |||
| 206 | #ifndef CONFIG_TCC_SYSINCLUDEPATHS | ||
| 207 | # ifndef TCC_TARGET_PE | ||
| 208 | # define CONFIG_TCC_SYSINCLUDEPATHS \ | 204 | # define CONFIG_TCC_SYSINCLUDEPATHS \ |
| 209 | ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \ | 205 | "{B}/include" \ |
| 206 | ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \ | ||
| 210 | ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include") | 207 | ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include") |
| 211 | # else | ||
| 212 | # define CONFIG_TCC_SYSINCLUDEPATHS "" | ||
| 213 | # endif | 208 | # endif |
| 214 | #endif | 209 | #endif |
| 215 | 210 | ||
| @@ -283,12 +278,6 @@ extern long double strtold (const char *__nptr, char **__endptr); · 67 unmodified lines | |||
| 283 | #define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1" | 278 | #define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1" |
| 284 | #endif | 279 | #endif |
| 285 | 280 | ||
| 286 | #ifdef TCC_TARGET_PE | ||
| 287 | #define PATHSEP ';' | ||
| 288 | #else | ||
| 289 | #define PATHSEP ':' | ||
| 290 | #endif | ||
| 291 | |||
| 292 | /* -------------------------------------------- */ | 281 | /* -------------------------------------------- */ |
| 293 | 282 | ||
| 294 | #include "libtcc.h" | 283 | #include "libtcc.h" |
| @@ -722,10 +711,7 @@ struct TCCState { · 427 unmodified lines | |||
| 722 | DLLReference **loaded_dlls; | 711 | DLLReference **loaded_dlls; |
| 723 | int nb_loaded_dlls; | 712 | int nb_loaded_dlls; |
| 724 | 713 | ||
| 725 | /* include paths, search order */ | 714 | /* include paths */ |
| 726 | char **tccinclude_paths; | ||
| 727 | int nb_tccinclude_paths; | ||
| 728 | |||
| 729 | char **include_paths; | 715 | char **include_paths; |
| 730 | int nb_include_paths; | 716 | int nb_include_paths; |
| 731 | 717 | ||
| @@ -1616,7 +1602,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str); · 884 unmodified lines | |||
| 1616 | ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd); | 1602 | ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd); |
| 1617 | ST_FUNC int pe_output_file(TCCState * s1, const char *filename); | 1603 | ST_FUNC int pe_output_file(TCCState * s1, const char *filename); |
| 1618 | ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value); | 1604 | ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value); |
| 1619 | #ifndef TCC_TARGET_ARM | 1605 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 |
| 1620 | ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2); | 1606 | ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2); |
| 1621 | #endif | 1607 | #endif |
| 1622 | #ifdef TCC_TARGET_X86_64 | 1608 | #ifdef TCC_TARGET_X86_64 |
| @@ -1628,7 +1614,6 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp); · 5 unmodified lines | |||
| 1628 | # define ST_PE_IMPORT 0x20 | 1614 | # define ST_PE_IMPORT 0x20 |
| 1629 | # define ST_PE_STDCALL 0x40 | 1615 | # define ST_PE_STDCALL 0x40 |
| 1630 | #endif | 1616 | #endif |
| 1631 | |||
| 1632 | /* ------------ tccrun.c ----------------- */ | 1617 | /* ------------ tccrun.c ----------------- */ |
| 1633 | #ifdef TCC_IS_NATIVE | 1618 | #ifdef TCC_IS_NATIVE |
| 1634 | #ifdef CONFIG_TCC_STATIC | 1619 | #ifdef CONFIG_TCC_STATIC |
| @@ -75,6 +75,8 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym) · 74 unmodified lines | |||
| 75 | sym->type.t &= ~VT_EXTERN; | 75 | sym->type.t &= ~VT_EXTERN; |
| 76 | /* Mark that this asm symbol doesn't need to be fed back. */ | 76 | /* Mark that this asm symbol doesn't need to be fed back. */ |
| 77 | sym->a.dllimport = 1; | 77 | sym->a.dllimport = 1; |
| 78 | } else { | ||
| 79 | sym->type.t |= VT_STATIC; | ||
| 78 | } | 80 | } |
| 79 | } | 81 | } |
| 80 | return sym; | 82 | return sym; |
| @@ -828,6 +828,12 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 827 unmodified lines | |||
| 828 | switch(type) { | 828 | switch(type) { |
| 829 | #if defined(TCC_TARGET_I386) | 829 | #if defined(TCC_TARGET_I386) |
| 830 | case R_386_32: | 830 | case R_386_32: |
| 831 | if (!get_sym_attr(s1, sym_index, 0)->dyn_index | ||
| 832 | && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) { | ||
| 833 | /* don't fixup unresolved (weak) symbols */ | ||
| 834 | rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE); | ||
| 835 | break; | ||
| 836 | } | ||
| 831 | #elif defined(TCC_TARGET_X86_64) | 837 | #elif defined(TCC_TARGET_X86_64) |
| 832 | case R_X86_64_32: | 838 | case R_X86_64_32: |
| 833 | case R_X86_64_32S: | 839 | case R_X86_64_32S: |
| @@ -1238,14 +1244,6 @@ static void tcc_output_binary(TCCState *s1, FILE *f, · 404 unmodified lines | |||
| 1238 | } | 1244 | } |
| 1239 | } | 1245 | } |
| 1240 | 1246 | ||
| 1241 | #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) | ||
| 1242 | #define HAVE_PHDR 1 | ||
| 1243 | #define EXTRA_RELITEMS 14 | ||
| 1244 | #else | ||
| 1245 | #define HAVE_PHDR 1 | ||
| 1246 | #define EXTRA_RELITEMS 9 | ||
| 1247 | #endif | ||
| 1248 | |||
| 1249 | ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) | 1247 | ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) |
| 1250 | { | 1248 | { |
| 1251 | int sym_index = ELFW(R_SYM) (rel->r_info); | 1249 | int sym_index = ELFW(R_SYM) (rel->r_info); |
| @@ -1413,13 +1411,12 @@ static void bind_libs_dynsyms(TCCState *s1) · 161 unmodified lines | |||
| 1413 | for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { | 1411 | for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { |
| 1414 | name = (char *) s1->dynsymtab_section->link->data + esym->st_name; | 1412 | name = (char *) s1->dynsymtab_section->link->data + esym->st_name; |
| 1415 | sym_index = find_elf_sym(symtab_section, name); | 1413 | sym_index = find_elf_sym(symtab_section, name); |
| 1416 | /* XXX: avoid adding a symbol if already present because of | ||
| 1417 | -rdynamic ? */ | ||
| 1418 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 1414 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 1419 | if (sym_index && sym->st_shndx != SHN_UNDEF) | 1415 | if (sym_index && sym->st_shndx != SHN_UNDEF |
| 1420 | set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, | 1416 | && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { |
| 1421 | 0, sym->st_shndx, name); | 1417 | set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, |
| 1422 | else if (esym->st_shndx == SHN_UNDEF) { | 1418 | sym->st_info, 0, sym->st_shndx, name); |
| 1419 | } else if (esym->st_shndx == SHN_UNDEF) { | ||
| 1423 | /* weak symbols can stay undefined */ | 1420 | /* weak symbols can stay undefined */ |
| 1424 | if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) | 1421 | if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) |
| 1425 | tcc_warning("undefined dynamic symbol '%s'", name); | 1422 | tcc_warning("undefined dynamic symbol '%s'", name); |
| @@ -1451,10 +1448,11 @@ static void export_global_syms(TCCState *s1) · 25 unmodified lines | |||
| 1451 | /* Allocate strings for section names and decide if an unallocated section | 1448 | /* Allocate strings for section names and decide if an unallocated section |
| 1452 | should be output. | 1449 | should be output. |
| 1453 | NOTE: the strsec section comes last, so its size is also correct ! */ | 1450 | NOTE: the strsec section comes last, so its size is also correct ! */ |
| 1454 | static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec) | 1451 | static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec) |
| 1455 | { | 1452 | { |
| 1456 | int i; | 1453 | int i; |
| 1457 | Section *s; | 1454 | Section *s; |
| 1455 | int textrel = 0; | ||
| 1458 | 1456 | ||
| 1459 | /* Allocate strings for section names */ | 1457 | /* Allocate strings for section names */ |
| 1460 | for(i = 1; i < s1->nb_sections; i++) { | 1458 | for(i = 1; i < s1->nb_sections; i++) { |
| @@ -1463,12 +1461,11 @@ static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec) · 2 unmodified lines | |||
| 1463 | patch them */ | 1461 | patch them */ |
| 1464 | if (file_type == TCC_OUTPUT_DLL && | 1462 | if (file_type == TCC_OUTPUT_DLL && |
| 1465 | s->sh_type == SHT_RELX && | 1463 | s->sh_type == SHT_RELX && |
| 1466 | !(s->sh_flags & SHF_ALLOC)) { | 1464 | !(s->sh_flags & SHF_ALLOC) && |
| 1467 | /* gr: avoid bogus relocs for empty (debug) sections */ | 1465 | (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) && |
| 1468 | if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) | 1466 | prepare_dynamic_rel(s1, s)) { |
| 1469 | prepare_dynamic_rel(s1, s); | 1467 | if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR) |
| 1470 | else if (s1->do_debug) | 1468 | textrel = 1; |
| 1471 | s->sh_size = s->data_offset; | ||
| 1472 | } else if (s1->do_debug || | 1469 | } else if (s1->do_debug || |
| 1473 | file_type == TCC_OUTPUT_OBJ || | 1470 | file_type == TCC_OUTPUT_OBJ || |
| 1474 | (s->sh_flags & SHF_ALLOC) || | 1471 | (s->sh_flags & SHF_ALLOC) || |
| @@ -1480,13 +1477,14 @@ static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec) · 5 unmodified lines | |||
| 1480 | s->sh_name = put_elf_str(strsec, s->name); | 1477 | s->sh_name = put_elf_str(strsec, s->name); |
| 1481 | } | 1478 | } |
| 1482 | strsec->sh_size = strsec->data_offset; | 1479 | strsec->sh_size = strsec->data_offset; |
| 1480 | return textrel; | ||
| 1483 | } | 1481 | } |
| 1484 | 1482 | ||
| 1485 | /* Info to be copied in dynamic section */ | 1483 | /* Info to be copied in dynamic section */ |
| 1486 | struct dyn_inf { | 1484 | struct dyn_inf { |
| 1487 | Section *dynamic; | 1485 | Section *dynamic; |
| 1488 | Section *dynstr; | 1486 | Section *dynstr; |
| 1489 | unsigned long dyn_rel_off; | 1487 | unsigned long data_offset; |
| 1490 | addr_t rel_addr; | 1488 | addr_t rel_addr; |
| 1491 | addr_t rel_size; | 1489 | addr_t rel_size; |
| 1492 | #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) | 1490 | #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) |
| @@ -1542,7 +1540,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 49 unmodified lines | |||
| 1542 | the program header table itself if needed. These are done later as | 1540 | the program header table itself if needed. These are done later as |
| 1543 | they require section layout to be done first. */ | 1541 | they require section layout to be done first. */ |
| 1544 | if (interp) | 1542 | if (interp) |
| 1545 | ph += 1 + HAVE_PHDR; | 1543 | ph += 2; |
| 1546 | 1544 | ||
| 1547 | /* dynamic relocation table information, for .dynamic section */ | 1545 | /* dynamic relocation table information, for .dynamic section */ |
| 1548 | dyninf->rel_addr = dyninf->rel_size = 0; | 1546 | dyninf->rel_addr = dyninf->rel_size = 0; |
| @@ -1684,19 +1682,14 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp, · 135 unmodified lines | |||
| 1684 | if (interp) { | 1682 | if (interp) { |
| 1685 | ph = &phdr[0]; | 1683 | ph = &phdr[0]; |
| 1686 | 1684 | ||
| 1687 | if (HAVE_PHDR) | 1685 | ph->p_type = PT_PHDR; |
| 1688 | { | 1686 | ph->p_offset = sizeof(ElfW(Ehdr)); |
| 1689 | int len = phnum * sizeof(ElfW(Phdr)); | 1687 | ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr)); |
| 1690 | 1688 | ph->p_vaddr = interp->sh_addr - ph->p_filesz; | |
| 1691 | ph->p_type = PT_PHDR; | 1689 | ph->p_paddr = ph->p_vaddr; |
| 1692 | ph->p_offset = sizeof(ElfW(Ehdr)); | 1690 | ph->p_flags = PF_R | PF_X; |
| 1693 | ph->p_vaddr = interp->sh_addr - len; | 1691 | ph->p_align = 4; /* interp->sh_addralign; */ |
| 1694 | ph->p_paddr = ph->p_vaddr; | 1692 | ph++; |
| 1695 | ph->p_filesz = ph->p_memsz = len; | ||
| 1696 | ph->p_flags = PF_R | PF_X; | ||
| 1697 | ph->p_align = 4; /* interp->sh_addralign; */ | ||
| 1698 | ph++; | ||
| 1699 | } | ||
| 1700 | 1693 | ||
| 1701 | ph->p_type = PT_INTERP; | 1694 | ph->p_type = PT_INTERP; |
| 1702 | ph->p_offset = interp->sh_offset; | 1695 | ph->p_offset = interp->sh_offset; |
| @@ -1727,12 +1720,9 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp, · 24 unmodified lines | |||
| 1727 | sections */ | 1720 | sections */ |
| 1728 | static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) | 1721 | static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) |
| 1729 | { | 1722 | { |
| 1730 | Section *dynamic; | 1723 | Section *dynamic = dyninf->dynamic; |
| 1731 | |||
| 1732 | dynamic = dyninf->dynamic; | ||
| 1733 | 1724 | ||
| 1734 | /* put dynamic section entries */ | 1725 | /* put dynamic section entries */ |
| 1735 | dynamic->data_offset = dyninf->dyn_rel_off; | ||
| 1736 | put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); | 1726 | put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); |
| 1737 | put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr); | 1727 | put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr); |
| 1738 | put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); | 1728 | put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); |
| @@ -2009,22 +1999,20 @@ static int elf_output_file(TCCState *s1, const char *filename) · 270 unmodified lines | |||
| 2009 | ElfW(Phdr) *phdr; | 1999 | ElfW(Phdr) *phdr; |
| 2010 | ElfW(Sym) *sym; | 2000 | ElfW(Sym) *sym; |
| 2011 | Section *strsec, *interp, *dynamic, *dynstr; | 2001 | Section *strsec, *interp, *dynamic, *dynstr; |
| 2002 | int textrel; | ||
| 2012 | 2003 | ||
| 2013 | file_type = s1->output_type; | 2004 | file_type = s1->output_type; |
| 2014 | s1->nb_errors = 0; | 2005 | s1->nb_errors = 0; |
| 2015 | 2006 | ret = -1; | |
| 2016 | /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ | ||
| 2017 | if (file_type != TCC_OUTPUT_OBJ) { | ||
| 2018 | tcc_add_runtime(s1); | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | phdr = NULL; | 2007 | phdr = NULL; |
| 2022 | sec_order = NULL; | 2008 | sec_order = NULL; |
| 2023 | interp = dynamic = dynstr = NULL; /* avoid warning */ | 2009 | interp = dynamic = dynstr = NULL; /* avoid warning */ |
| 2010 | textrel = 0; | ||
| 2024 | 2011 | ||
| 2025 | if (file_type != TCC_OUTPUT_OBJ) { | 2012 | if (file_type != TCC_OUTPUT_OBJ) { |
| 2013 | /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ | ||
| 2014 | tcc_add_runtime(s1); | ||
| 2026 | relocate_common_syms(); | 2015 | relocate_common_syms(); |
| 2027 | |||
| 2028 | tcc_add_linker_symbols(s1); | 2016 | tcc_add_linker_symbols(s1); |
| 2029 | 2017 | ||
| 2030 | if (!s1->static_link) { | 2018 | if (!s1->static_link) { |
| @@ -2057,52 +2045,69 @@ static int elf_output_file(TCCState *s1, const char *filename) · 26 unmodified lines | |||
| 2057 | 2045 | ||
| 2058 | if (file_type == TCC_OUTPUT_EXE) { | 2046 | if (file_type == TCC_OUTPUT_EXE) { |
| 2059 | bind_exe_dynsyms(s1); | 2047 | bind_exe_dynsyms(s1); |
| 2060 | 2048 | if (s1->nb_errors) | |
| 2061 | if (s1->nb_errors) { | ||
| 2062 | ret = -1; | ||
| 2063 | goto the_end; | 2049 | goto the_end; |
| 2064 | } | ||
| 2065 | |||
| 2066 | bind_libs_dynsyms(s1); | 2050 | bind_libs_dynsyms(s1); |
| 2067 | } else /* shared library case: simply export all global symbols */ | 2051 | } else { |
| 2052 | /* shared library case: simply export all global symbols */ | ||
| 2068 | export_global_syms(s1); | 2053 | export_global_syms(s1); |
| 2054 | } | ||
| 2055 | } | ||
| 2056 | build_got_entries(s1); | ||
| 2057 | } | ||
| 2069 | 2058 | ||
| 2070 | build_got_entries(s1); | 2059 | /* we add a section for symbols */ |
| 2060 | strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); | ||
| 2061 | put_elf_str(strsec, ""); | ||
| 2071 | 2062 | ||
| 2072 | /* add a list of needed dlls */ | 2063 | /* Allocate strings for section names */ |
| 2073 | for(i = 0; i < s1->nb_loaded_dlls; i++) { | 2064 | textrel = alloc_sec_names(s1, file_type, strsec); |
| 2074 | DLLReference *dllref = s1->loaded_dlls[i]; | ||
| 2075 | if (dllref->level == 0) | ||
| 2076 | put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); | ||
| 2077 | } | ||
| 2078 | 2065 | ||
| 2079 | if (s1->rpath) | 2066 | if (dynamic) { |
| 2080 | put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH, | 2067 | /* add a list of needed dlls */ |
| 2081 | put_elf_str(dynstr, s1->rpath)); | 2068 | for(i = 0; i < s1->nb_loaded_dlls; i++) { |
| 2069 | DLLReference *dllref = s1->loaded_dlls[i]; | ||
| 2070 | if (dllref->level == 0) | ||
| 2071 | put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); | ||
| 2072 | } | ||
| 2082 | 2073 | ||
| 2074 | if (s1->rpath) | ||
| 2075 | put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH, | ||
| 2076 | put_elf_str(dynstr, s1->rpath)); | ||
| 2077 | |||
| 2078 | if (file_type == TCC_OUTPUT_DLL) { | ||
| 2079 | if (s1->soname) | ||
| 2080 | put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); | ||
| 2083 | /* XXX: currently, since we do not handle PIC code, we | 2081 | /* XXX: currently, since we do not handle PIC code, we |
| 2084 | must relocate the readonly segments */ | 2082 | must relocate the readonly segments */ |
| 2085 | if (file_type == TCC_OUTPUT_DLL) { | 2083 | if (textrel) |
| 2086 | if (s1->soname) | ||
| 2087 | put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); | ||
| 2088 | put_dt(dynamic, DT_TEXTREL, 0); | 2084 | put_dt(dynamic, DT_TEXTREL, 0); |
| 2089 | } | 2085 | } |
| 2090 | 2086 | ||
| 2091 | if (s1->symbolic) | 2087 | if (s1->symbolic) |
| 2092 | put_dt(dynamic, DT_SYMBOLIC, 0); | 2088 | put_dt(dynamic, DT_SYMBOLIC, 0); |
| 2093 | 2089 | ||
| 2094 | /* add necessary space for other entries */ | 2090 | dyninf.dynamic = dynamic; |
| 2095 | dyninf.dyn_rel_off = dynamic->data_offset; | 2091 | dyninf.dynstr = dynstr; |
| 2096 | dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS; | 2092 | /* remember offset and reserve space for 2nd call below */ |
| 2097 | } else { | 2093 | dyninf.data_offset = dynamic->data_offset; |
| 2098 | /* still need to build got entries in case of static link */ | 2094 | fill_dynamic(s1, &dyninf); |
| 2099 | build_got_entries(s1); | 2095 | dynamic->sh_size = dynamic->data_offset; |
| 2100 | } | 2096 | dynstr->sh_size = dynstr->data_offset; |
| 2101 | } | 2097 | } |
| 2102 | 2098 | ||
| 2103 | /* we add a section for symbols */ | 2099 | /* compute number of program headers */ |
| 2104 | strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); | 2100 | if (file_type == TCC_OUTPUT_OBJ) |
| 2105 | put_elf_str(strsec, ""); | 2101 | phnum = 0; |
| 2102 | else if (file_type == TCC_OUTPUT_DLL) | ||
| 2103 | phnum = 3; | ||
| 2104 | else if (s1->static_link) | ||
| 2105 | phnum = 2; | ||
| 2106 | else | ||
| 2107 | phnum = 5; | ||
| 2108 | |||
| 2109 | /* allocate program segment headers */ | ||
| 2110 | phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); | ||
| 2106 | 2111 | ||
| 2107 | /* compute number of sections */ | 2112 | /* compute number of sections */ |
| 2108 | shnum = s1->nb_sections; | 2113 | shnum = s1->nb_sections; |
| @@ -2111,41 +2116,16 @@ static int elf_output_file(TCCState *s1, const char *filename) · 2 unmodified lines | |||
| 2111 | sec_order = tcc_malloc(sizeof(int) * shnum); | 2116 | sec_order = tcc_malloc(sizeof(int) * shnum); |
| 2112 | sec_order[0] = 0; | 2117 | sec_order[0] = 0; |
| 2113 | 2118 | ||
| 2114 | /* compute number of program headers */ | ||
| 2115 | switch(file_type) { | ||
| 2116 | default: | ||
| 2117 | case TCC_OUTPUT_OBJ: | ||
| 2118 | phnum = 0; | ||
| 2119 | break; | ||
| 2120 | case TCC_OUTPUT_EXE: | ||
| 2121 | if (!s1->static_link) | ||
| 2122 | phnum = 4 + HAVE_PHDR; | ||
| 2123 | else | ||
| 2124 | phnum = 2; | ||
| 2125 | break; | ||
| 2126 | case TCC_OUTPUT_DLL: | ||
| 2127 | phnum = 3; | ||
| 2128 | break; | ||
| 2129 | } | ||
| 2130 | |||
| 2131 | /* Allocate strings for section names */ | ||
| 2132 | alloc_sec_names(s1, file_type, strsec); | ||
| 2133 | |||
| 2134 | /* allocate program segment headers */ | ||
| 2135 | phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); | ||
| 2136 | |||
| 2137 | /* compute section to program header mapping */ | 2119 | /* compute section to program header mapping */ |
| 2138 | file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf, | 2120 | file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf, |
| 2139 | sec_order); | 2121 | sec_order); |
| 2140 | 2122 | ||
| 2141 | /* Fill remaining program header and finalize relocation related to dynamic | 2123 | /* Fill remaining program header and finalize relocation related to dynamic |
| 2142 | linking. */ | 2124 | linking. */ |
| 2143 | if (phnum > 0) { | 2125 | if (file_type != TCC_OUTPUT_OBJ) { |
| 2144 | fill_unloadable_phdr(phdr, phnum, interp, dynamic); | 2126 | fill_unloadable_phdr(phdr, phnum, interp, dynamic); |
| 2145 | if (dynamic) { | 2127 | if (dynamic) { |
| 2146 | dyninf.dynamic = dynamic; | 2128 | dynamic->data_offset = dyninf.data_offset; |
| 2147 | dyninf.dynstr = dynstr; | ||
| 2148 | |||
| 2149 | fill_dynamic(s1, &dyninf); | 2129 | fill_dynamic(s1, &dyninf); |
| 2150 | 2130 | ||
| 2151 | /* put in GOT the dynamic section address and relocate PLT */ | 2131 | /* put in GOT the dynamic section address and relocate PLT */ |
| @@ -2162,22 +2142,20 @@ static int elf_output_file(TCCState *s1, const char *filename) · 10 unmodified lines | |||
| 2162 | } | 2142 | } |
| 2163 | } | 2143 | } |
| 2164 | } | 2144 | } |
| 2165 | } | ||
| 2166 | 2145 | ||
| 2167 | /* if building executable or DLL, then relocate each section | 2146 | /* if building executable or DLL, then relocate each section |
| 2168 | except the GOT which is already relocated */ | 2147 | except the GOT which is already relocated */ |
| 2169 | if (file_type != TCC_OUTPUT_OBJ) { | ||
| 2170 | ret = final_sections_reloc(s1); | 2148 | ret = final_sections_reloc(s1); |
| 2171 | if (ret) | 2149 | if (ret) |
| 2172 | goto the_end; | 2150 | goto the_end; |
| 2173 | tidy_section_headers(s1, sec_order); | 2151 | tidy_section_headers(s1, sec_order); |
| 2174 | } | ||
| 2175 | 2152 | ||
| 2176 | /* Perform relocation to GOT or PLT entries */ | 2153 | /* Perform relocation to GOT or PLT entries */ |
| 2177 | if (file_type == TCC_OUTPUT_EXE && s1->static_link) | 2154 | if (file_type == TCC_OUTPUT_EXE && s1->static_link) |
| 2178 | fill_got(s1); | 2155 | fill_got(s1); |
| 2179 | else if (s1->got) | 2156 | else if (s1->got) |
| 2180 | fill_local_got_entries(s1); | 2157 | fill_local_got_entries(s1); |
| 2158 | } | ||
| 2181 | 2159 | ||
| 2182 | /* Create the ELF file with name 'filename' */ | 2160 | /* Create the ELF file with name 'filename' */ |
| 2183 | ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); | 2161 | ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); |
| @@ -116,6 +116,12 @@ ST_FUNC int ieee_finite(double d) · 115 unmodified lines | |||
| 116 | return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; | 116 | return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | /* compiling intel long double natively */ | ||
| 120 | #if (defined __i386__ || defined __x86_64__) \ | ||
| 121 | && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) | ||
| 122 | # define TCC_IS_NATIVE_387 | ||
| 123 | #endif | ||
| 124 | |||
| 119 | ST_FUNC void test_lvalue(void) | 125 | ST_FUNC void test_lvalue(void) |
| 120 | { | 126 | { |
| 121 | if (!(vtop->r & VT_LVAL)) | 127 | if (!(vtop->r & VT_LVAL)) |
| @@ -267,9 +273,6 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 145 unmodified lines | |||
| 267 | parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; | 273 | parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; |
| 268 | next(); | 274 | next(); |
| 269 | decl(VT_CONST); | 275 | decl(VT_CONST); |
| 270 | if (tok != TOK_EOF) | ||
| 271 | expect("declaration"); | ||
| 272 | |||
| 273 | gen_inline_functions(s1); | 276 | gen_inline_functions(s1); |
| 274 | check_vstack(); | 277 | check_vstack(); |
| 275 | /* end of translation unit info */ | 278 | /* end of translation unit info */ |
| @@ -2411,6 +2414,9 @@ static void gen_cast(CType *type) · 2135 unmodified lines | |||
| 2411 | df = is_float(dbt); | 2414 | df = is_float(dbt); |
| 2412 | c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; | 2415 | c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| 2413 | p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM); | 2416 | p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM); |
| 2417 | #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387 | ||
| 2418 | c &= dbt != VT_LDOUBLE; | ||
| 2419 | #endif | ||
| 2414 | if (c) { | 2420 | if (c) { |
| 2415 | /* constant case: we can do it now */ | 2421 | /* constant case: we can do it now */ |
| 2416 | /* XXX: in ISOC, cannot do it if error in convert */ | 2422 | /* XXX: in ISOC, cannot do it if error in convert */ |
| @@ -3096,6 +3102,8 @@ ST_FUNC void vstore(void) · 679 unmodified lines | |||
| 3096 | /* ... and discard */ | 3102 | /* ... and discard */ |
| 3097 | vpop(); | 3103 | vpop(); |
| 3098 | } | 3104 | } |
| 3105 | } else if (dbt == VT_VOID) { | ||
| 3106 | --vtop; | ||
| 3099 | } else { | 3107 | } else { |
| 3100 | #ifdef CONFIG_TCC_BCHECK | 3108 | #ifdef CONFIG_TCC_BCHECK |
| 3101 | /* bound check case */ | 3109 | /* bound check case */ |
| @@ -5925,7 +5933,10 @@ static void block(int *bsym, int *csym, int is_expr) · 2823 unmodified lines | |||
| 5925 | if (tok != ';') { | 5933 | if (tok != ';') { |
| 5926 | gexpr(); | 5934 | gexpr(); |
| 5927 | gen_assign_cast(&func_vt); | 5935 | gen_assign_cast(&func_vt); |
| 5928 | gfunc_return(&func_vt); | 5936 | if ((func_vt.t & VT_BTYPE) == VT_VOID) |
| 5937 | vtop--; | ||
| 5938 | else | ||
| 5939 | gfunc_return(&func_vt); | ||
| 5929 | } | 5940 | } |
| 5930 | skip(';'); | 5941 | skip(';'); |
| 5931 | /* jump unless last stmt in top-level block */ | 5942 | /* jump unless last stmt in top-level block */ |
| @@ -6483,7 +6494,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 551 unmodified lines | |||
| 6483 | *(double *)ptr = vtop->c.d; | 6494 | *(double *)ptr = vtop->c.d; |
| 6484 | break; | 6495 | break; |
| 6485 | case VT_LDOUBLE: | 6496 | case VT_LDOUBLE: |
| 6486 | #if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) | 6497 | #if defined TCC_IS_NATIVE_387 |
| 6487 | if (sizeof (long double) >= 10) /* zero pad ten-byte LD */ | 6498 | if (sizeof (long double) >= 10) /* zero pad ten-byte LD */ |
| 6488 | memcpy(ptr, &vtop->c.ld, 10); | 6499 | memcpy(ptr, &vtop->c.ld, 10); |
| 6489 | #ifdef __TINYC__ | 6500 | #ifdef __TINYC__ |
| @@ -7091,17 +7102,22 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 601 unmodified lines | |||
| 7091 | next(); | 7102 | next(); |
| 7092 | continue; | 7103 | continue; |
| 7093 | } | 7104 | } |
| 7094 | if (l == VT_CONST && | 7105 | if (l != VT_CONST) |
| 7095 | (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { | 7106 | break; |
| 7107 | if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { | ||
| 7096 | /* global asm block */ | 7108 | /* global asm block */ |
| 7097 | asm_global_instr(); | 7109 | asm_global_instr(); |
| 7098 | continue; | 7110 | continue; |
| 7099 | } | 7111 | } |
| 7100 | /* special test for old K&R protos without explicit int | 7112 | if (tok >= TOK_UIDENT) { |
| 7101 | type. Only accepted when defining global data */ | 7113 | /* special test for old K&R protos without explicit int |
| 7102 | if (l != VT_CONST || tok < TOK_UIDENT) | 7114 | type. Only accepted when defining global data */ |
| 7115 | btype.t = VT_INT; | ||
| 7116 | } else { | ||
| 7117 | if (tok != TOK_EOF) | ||
| 7118 | expect("declaration"); | ||
| 7103 | break; | 7119 | break; |
| 7104 | btype.t = VT_INT; | 7120 | } |
| 7105 | } | 7121 | } |
| 7106 | if (tok == ';') { | 7122 | if (tok == ';') { |
| 7107 | if ((btype.t & VT_BTYPE) == VT_STRUCT) { | 7123 | if ((btype.t & VT_BTYPE) == VT_STRUCT) { |
| @@ -26,10 +26,12 @@ · 25 unmodified lines | |||
| 26 | #ifndef _WIN32 | 26 | #ifndef _WIN32 |
| 27 | #define stricmp strcasecmp | 27 | #define stricmp strcasecmp |
| 28 | #define strnicmp strncasecmp | 28 | #define strnicmp strncasecmp |
| 29 | #include <sys/stat.h> /* chmod() */ | ||
| 29 | #endif | 30 | #endif |
| 30 | 31 | ||
| 31 | #ifdef TCC_TARGET_X86_64 | 32 | #ifdef TCC_TARGET_X86_64 |
| 32 | # define ADDR3264 ULONGLONG | 33 | # define ADDR3264 ULONGLONG |
| 34 | # define PE_IMAGE_REL IMAGE_REL_BASED_DIR64 | ||
| 33 | # define REL_TYPE_DIRECT R_X86_64_64 | 35 | # define REL_TYPE_DIRECT R_X86_64_64 |
| 34 | # define R_XXX_THUNKFIX R_X86_64_PC32 | 36 | # define R_XXX_THUNKFIX R_X86_64_PC32 |
| 35 | # define R_XXX_RELATIVE R_X86_64_RELATIVE | 37 | # define R_XXX_RELATIVE R_X86_64_RELATIVE |
| @@ -38,6 +40,7 @@ · 2 unmodified lines | |||
| 38 | 40 | ||
| 39 | #elif defined TCC_TARGET_ARM | 41 | #elif defined TCC_TARGET_ARM |
| 40 | # define ADDR3264 DWORD | 42 | # define ADDR3264 DWORD |
| 43 | # define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW | ||
| 41 | # define REL_TYPE_DIRECT R_ARM_ABS32 | 44 | # define REL_TYPE_DIRECT R_ARM_ABS32 |
| 42 | # define R_XXX_THUNKFIX R_ARM_ABS32 | 45 | # define R_XXX_THUNKFIX R_ARM_ABS32 |
| 43 | # define R_XXX_RELATIVE R_ARM_RELATIVE | 46 | # define R_XXX_RELATIVE R_ARM_RELATIVE |
| @@ -46,6 +49,7 @@ · 2 unmodified lines | |||
| 46 | 49 | ||
| 47 | #elif defined TCC_TARGET_I386 | 50 | #elif defined TCC_TARGET_I386 |
| 48 | # define ADDR3264 DWORD | 51 | # define ADDR3264 DWORD |
| 52 | # define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW | ||
| 49 | # define REL_TYPE_DIRECT R_386_32 | 53 | # define REL_TYPE_DIRECT R_386_32 |
| 50 | # define R_XXX_THUNKFIX R_386_32 | 54 | # define R_XXX_THUNKFIX R_386_32 |
| 51 | # define R_XXX_RELATIVE R_386_RELATIVE | 55 | # define R_XXX_RELATIVE R_386_RELATIVE |
| @@ -54,22 +58,6 @@ · 2 unmodified lines | |||
| 54 | 58 | ||
| 55 | #endif | 59 | #endif |
| 56 | 60 | ||
| 57 | #if 0 | ||
| 58 | #ifdef _WIN32 | ||
| 59 | void dbg_printf (const char *fmt, ...) | ||
| 60 | { | ||
| 61 | char buffer[4000]; | ||
| 62 | va_list arg; | ||
| 63 | int x; | ||
| 64 | va_start(arg, fmt); | ||
| 65 | x = vsprintf (buffer, fmt, arg); | ||
| 66 | strcpy(buffer+x, "\n"); | ||
| 67 | OutputDebugString(buffer); | ||
| 68 | } | ||
| 69 | #endif | ||
| 70 | #endif | ||
| 71 | |||
| 72 | /* ----------------------------------------------------------- */ | ||
| 73 | #ifndef IMAGE_NT_SIGNATURE | 61 | #ifndef IMAGE_NT_SIGNATURE |
| 74 | /* ----------------------------------------------------------- */ | 62 | /* ----------------------------------------------------------- */ |
| 75 | /* definitions below are from winnt.h */ | 63 | /* definitions below are from winnt.h */ |
| @@ -241,14 +229,19 @@ typedef struct _IMAGE_BASE_RELOCATION { · 165 unmodified lines | |||
| 241 | #define IMAGE_REL_BASED_MIPS_JMPADDR 5 | 229 | #define IMAGE_REL_BASED_MIPS_JMPADDR 5 |
| 242 | #define IMAGE_REL_BASED_SECTION 6 | 230 | #define IMAGE_REL_BASED_SECTION 6 |
| 243 | #define IMAGE_REL_BASED_REL32 7 | 231 | #define IMAGE_REL_BASED_REL32 7 |
| 232 | #define IMAGE_REL_BASED_DIR64 10 | ||
| 244 | 233 | ||
| 245 | #pragma pack(pop) | 234 | #pragma pack(pop) |
| 246 | 235 | ||
| 247 | /* ----------------------------------------------------------- */ | 236 | /* ----------------------------------------------------------- */ |
| 248 | #endif /* ndef IMAGE_NT_SIGNATURE */ | 237 | #endif /* ndef IMAGE_NT_SIGNATURE */ |
| 249 | /* ----------------------------------------------------------- */ | 238 | /* ----------------------------------------------------------- */ |
| 250 | #pragma pack(push, 1) | ||
| 251 | 239 | ||
| 240 | #ifndef IMAGE_REL_BASED_DIR64 | ||
| 241 | # define IMAGE_REL_BASED_DIR64 10 | ||
| 242 | #endif | ||
| 243 | |||
| 244 | #pragma pack(push, 1) | ||
| 252 | struct pe_header | 245 | struct pe_header |
| 253 | { | 246 | { |
| 254 | IMAGE_DOS_HEADER doshdr; | 247 | IMAGE_DOS_HEADER doshdr; |
| @@ -281,7 +274,6 @@ struct pe_rsrc_reloc { · 26 unmodified lines | |||
| 281 | DWORD size; | 274 | DWORD size; |
| 282 | WORD type; | 275 | WORD type; |
| 283 | }; | 276 | }; |
| 284 | |||
| 285 | #pragma pack(pop) | 277 | #pragma pack(pop) |
| 286 | 278 | ||
| 287 | /* ------------------------------------------------------------- */ | 279 | /* ------------------------------------------------------------- */ |
| @@ -732,6 +724,9 @@ static int pe_write(struct pe_info *pe) · 444 unmodified lines | |||
| 732 | fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET); | 724 | fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET); |
| 733 | pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL); | 725 | pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL); |
| 734 | fclose (op); | 726 | fclose (op); |
| 727 | #ifndef _WIN32 | ||
| 728 | chmod(pe->filename, 0777); | ||
| 729 | #endif | ||
| 735 | 730 | ||
| 736 | if (2 == pe->s1->verbose) | 731 | if (2 == pe->s1->verbose) |
| 737 | printf("-------------------------------\n"); | 732 | printf("-------------------------------\n"); |
| @@ -1017,7 +1012,7 @@ static void pe_build_reloc (struct pe_info *pe) · 279 unmodified lines | |||
| 1017 | } | 1012 | } |
| 1018 | if ((addr -= offset) < (1<<12)) { /* one block spans 4k addresses */ | 1013 | if ((addr -= offset) < (1<<12)) { /* one block spans 4k addresses */ |
| 1019 | WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD)); | 1014 | WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD)); |
| 1020 | *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12; | 1015 | *wp = addr | PE_IMAGE_REL<<12; |
| 1021 | ++count; | 1016 | ++count; |
| 1022 | continue; | 1017 | continue; |
| 1023 | } | 1018 | } |
| @@ -1471,7 +1466,7 @@ static void pe_print_sections(TCCState *s1, const char *fname) · 447 unmodified lines | |||
| 1471 | /* ------------------------------------------------------------- */ | 1466 | /* ------------------------------------------------------------- */ |
| 1472 | /* helper function for load/store to insert one more indirection */ | 1467 | /* helper function for load/store to insert one more indirection */ |
| 1473 | 1468 | ||
| 1474 | #ifndef TCC_TARGET_ARM | 1469 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 |
| 1475 | ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2) | 1470 | ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2) |
| 1476 | { | 1471 | { |
| 1477 | int r2; | 1472 | int r2; |
| @@ -591,7 +591,7 @@ ST_FUNC int handle_eob(void) · 590 unmodified lines | |||
| 591 | 591 | ||
| 592 | /* only tries to read if really end of buffer */ | 592 | /* only tries to read if really end of buffer */ |
| 593 | if (bf->buf_ptr >= bf->buf_end) { | 593 | if (bf->buf_ptr >= bf->buf_end) { |
| 594 | if (bf->fd != -1) { | 594 | if (bf->fd >= 0) { |
| 595 | #if defined(PARSE_DEBUG) | 595 | #if defined(PARSE_DEBUG) |
| 596 | len = 1; | 596 | len = 1; |
| 597 | #else | 597 | #else |
| @@ -1803,8 +1803,7 @@ ST_FUNC void preprocess(int is_bof) · 1205 unmodified lines | |||
| 1803 | /* store current file in stack, but increment stack later below */ | 1803 | /* store current file in stack, but increment stack later below */ |
| 1804 | *s1->include_stack_ptr = file; | 1804 | *s1->include_stack_ptr = file; |
| 1805 | i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0; | 1805 | i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0; |
| 1806 | n = 2 + s1->nb_tccinclude_paths + s1->nb_include_paths + | 1806 | n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths; |
| 1807 | s1->nb_sysinclude_paths; | ||
| 1808 | for (; i < n; ++i) { | 1807 | for (; i < n; ++i) { |
| 1809 | char buf1[sizeof file->filename]; | 1808 | char buf1[sizeof file->filename]; |
| 1810 | CachedInclude *e; | 1809 | CachedInclude *e; |
| @@ -1826,14 +1825,8 @@ ST_FUNC void preprocess(int is_bof) · 15 unmodified lines | |||
| 1826 | 1825 | ||
| 1827 | } else { | 1826 | } else { |
| 1828 | /* search in all the include paths */ | 1827 | /* search in all the include paths */ |
| 1829 | int k, j = i - 2; | 1828 | int j = i - 2, k = j - s1->nb_include_paths; |
| 1830 | 1829 | path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k]; | |
| 1831 | if (j < (k = s1->nb_tccinclude_paths)) | ||
| 1832 | path = s1->tccinclude_paths[j]; | ||
| 1833 | else if ((j -= k) < s1->nb_include_paths) | ||
| 1834 | path = s1->include_paths[j]; | ||
| 1835 | else if ((j -= s1->nb_include_paths) < s1->nb_sysinclude_paths) | ||
| 1836 | path = s1->sysinclude_paths[j]; | ||
| 1837 | pstrcpy(buf1, sizeof(buf1), path); | 1830 | pstrcpy(buf1, sizeof(buf1), path); |
| 1838 | pstrcat(buf1, sizeof(buf1), "/"); | 1831 | pstrcat(buf1, sizeof(buf1), "/"); |
| 1839 | } | 1832 | } |
| @@ -2635,6 +2628,8 @@ static inline void next_nomacro1(void) · 795 unmodified lines | |||
| 2635 | tcc_close(); | 2628 | tcc_close(); |
| 2636 | s1->include_stack_ptr--; | 2629 | s1->include_stack_ptr--; |
| 2637 | p = file->buf_ptr; | 2630 | p = file->buf_ptr; |
| 2631 | if (p == file->buffer) | ||
| 2632 | tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL; | ||
| 2638 | goto redo_no_start; | 2633 | goto redo_no_start; |
| 2639 | } | 2634 | } |
| 2640 | } | 2635 | } |
| @@ -2968,7 +2963,7 @@ maybe_newline: · 327 unmodified lines | |||
| 2968 | keep_tok_flags: | 2963 | keep_tok_flags: |
| 2969 | file->buf_ptr = p; | 2964 | file->buf_ptr = p; |
| 2970 | #if defined(PARSE_DEBUG) | 2965 | #if defined(PARSE_DEBUG) |
| 2971 | printf("token = %s\n", get_tok_str(tok, &tokc)); | 2966 | printf("token = %d %s\n", tok, get_tok_str(tok, &tokc)); |
| 2972 | #endif | 2967 | #endif |
| 2973 | } | 2968 | } |
| 2974 | 2969 | ||
| @@ -3585,7 +3580,8 @@ ST_INLN void unget_tok(int last_tok) · 610 unmodified lines | |||
| 3585 | 3580 | ||
| 3586 | ST_FUNC void preprocess_start(TCCState *s1, int is_asm) | 3581 | ST_FUNC void preprocess_start(TCCState *s1, int is_asm) |
| 3587 | { | 3582 | { |
| 3588 | char *buf; | 3583 | CString cstr; |
| 3584 | int i; | ||
| 3589 | 3585 | ||
| 3590 | s1->include_stack_ptr = s1->include_stack; | 3586 | s1->include_stack_ptr = s1->include_stack; |
| 3591 | s1->ifdef_stack_ptr = s1->ifdef_stack; | 3587 | s1->ifdef_stack_ptr = s1->ifdef_stack; |
| @@ -3601,25 +3597,24 @@ ST_FUNC void preprocess_start(TCCState *s1, int is_asm) · 9 unmodified lines | |||
| 3601 | set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0); | 3597 | set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0); |
| 3602 | set_idnum('.', is_asm ? IS_ID : 0); | 3598 | set_idnum('.', is_asm ? IS_ID : 0); |
| 3603 | 3599 | ||
| 3604 | buf = tcc_malloc(3 + strlen(file->filename)); | 3600 | cstr_new(&cstr); |
| 3605 | sprintf(buf, "\"%s\"", file->filename); | 3601 | cstr_cat(&cstr, "\"", -1); |
| 3606 | tcc_define_symbol(s1, "__BASE_FILE__", buf); | 3602 | cstr_cat(&cstr, file->filename, -1); |
| 3607 | tcc_free(buf); | 3603 | cstr_cat(&cstr, "\"", 0); |
| 3608 | 3604 | tcc_define_symbol(s1, "__BASE_FILE__", cstr.data); | |
| 3609 | if (s1->nb_cmd_include_files) { | 3605 | |
| 3610 | CString cstr; | 3606 | cstr_reset(&cstr); |
| 3611 | int i; | 3607 | for (i = 0; i < s1->nb_cmd_include_files; i++) { |
| 3612 | cstr_new(&cstr); | 3608 | cstr_cat(&cstr, "#include \"", -1); |
| 3613 | for (i = 0; i < s1->nb_cmd_include_files; i++) { | 3609 | cstr_cat(&cstr, s1->cmd_include_files[i], -1); |
| 3614 | cstr_cat(&cstr, "#include \"", -1); | 3610 | cstr_cat(&cstr, "\"\n", -1); |
| 3615 | cstr_cat(&cstr, s1->cmd_include_files[i], -1); | 3611 | } |
| 3616 | cstr_cat(&cstr, "\"\n", -1); | 3612 | if (cstr.size) { |
| 3617 | } | ||
| 3618 | *s1->include_stack_ptr++ = file; | 3613 | *s1->include_stack_ptr++ = file; |
| 3619 | tcc_open_bf(s1, "<command line>", cstr.size); | 3614 | tcc_open_bf(s1, "<command line>", cstr.size); |
| 3620 | memcpy(file->buffer, cstr.data, cstr.size); | 3615 | memcpy(file->buffer, cstr.data, cstr.size); |
| 3621 | cstr_free(&cstr); | ||
| 3622 | } | 3616 | } |
| 3617 | cstr_free(&cstr); | ||
| 3623 | 3618 | ||
| 3624 | if (is_asm) | 3619 | if (is_asm) |
| 3625 | tcc_define_symbol(s1, "__ASSEMBLER__", NULL); | 3620 | tcc_define_symbol(s1, "__ASSEMBLER__", NULL); |
| @@ -45,15 +45,13 @@ static void set_exception_handler(void); · 44 unmodified lines | |||
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | static void set_pages_executable(void *ptr, unsigned long length); | 47 | static void set_pages_executable(void *ptr, unsigned long length); |
| 48 | static int tcc_relocate_ex(TCCState *s1, void *ptr); | 48 | static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff); |
| 49 | 49 | ||
| 50 | #ifdef _WIN64 | 50 | #ifdef _WIN64 |
| 51 | static void *win64_add_function_table(TCCState *s1); | 51 | static void *win64_add_function_table(TCCState *s1); |
| 52 | static void win64_del_function_table(void *); | 52 | static void win64_del_function_table(void *); |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | // #define HAVE_SELINUX | ||
| 56 | |||
| 57 | /* ------------------------------------------------------------- */ | 55 | /* ------------------------------------------------------------- */ |
| 58 | /* Do all relocations (needed before using tcc_get_symbol()) | 56 | /* Do all relocations (needed before using tcc_get_symbol()) |
| 59 | Returns -1 on error. */ | 57 | Returns -1 on error. */ |
| @@ -61,25 +59,36 @@ static void win64_del_function_table(void *); · 1 unmodified line | |||
| 61 | LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) | 59 | LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) |
| 62 | { | 60 | { |
| 63 | int size; | 61 | int size; |
| 62 | addr_t ptr_diff = 0; | ||
| 64 | 63 | ||
| 65 | if (TCC_RELOCATE_AUTO != ptr) | 64 | if (TCC_RELOCATE_AUTO != ptr) |
| 66 | return tcc_relocate_ex(s1, ptr); | 65 | return tcc_relocate_ex(s1, ptr, 0); |
| 67 | 66 | ||
| 68 | size = tcc_relocate_ex(s1, NULL); | 67 | size = tcc_relocate_ex(s1, NULL, 0); |
| 69 | if (size < 0) | 68 | if (size < 0) |
| 70 | return -1; | 69 | return -1; |
| 71 | 70 | ||
| 72 | #ifdef HAVE_SELINUX | 71 | #ifdef HAVE_SELINUX |
| 73 | /* Use mmap instead of malloc for Selinux. */ | 72 | { |
| 74 | ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, | 73 | /* Using mmap instead of malloc */ |
| 75 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 74 | void *prx; |
| 76 | if (ptr == MAP_FAILED) | 75 | char tmpfname[] = "/tmp/.tccrunXXXXXX"; |
| 77 | tcc_error("tccrun: could not map memory"); | 76 | int fd = mkstemp(tmpfname); |
| 77 | unlink(tmpfname); | ||
| 78 | ftruncate(fd, size); | ||
| 79 | |||
| 80 | ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | ||
| 81 | prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0); | ||
| 82 | if (ptr == MAP_FAILED || prx == MAP_FAILED) | ||
| 83 | tcc_error("tccrun: could not map memory"); | ||
| 78 | dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size); | 84 | dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size); |
| 85 | dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx); | ||
| 86 | ptr_diff = (char*)prx - (char*)ptr; | ||
| 87 | } | ||
| 79 | #else | 88 | #else |
| 80 | ptr = tcc_malloc(size); | 89 | ptr = tcc_malloc(size); |
| 81 | #endif | 90 | #endif |
| 82 | tcc_relocate_ex(s1, ptr); /* no more errors expected */ | 91 | tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */ |
| 83 | dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr); | 92 | dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr); |
| 84 | return 0; | 93 | return 0; |
| 85 | } | 94 | } |
| @@ -91,6 +100,7 @@ ST_FUNC void tcc_run_free(TCCState *s1) · 5 unmodified lines | |||
| 91 | for (i = 0; i < s1->nb_runtime_mem; ++i) { | 100 | for (i = 0; i < s1->nb_runtime_mem; ++i) { |
| 92 | #ifdef HAVE_SELINUX | 101 | #ifdef HAVE_SELINUX |
| 93 | unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++]; | 102 | unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++]; |
| 103 | munmap(s1->runtime_mem[i++], size); | ||
| 94 | munmap(s1->runtime_mem[i], size); | 104 | munmap(s1->runtime_mem[i], size); |
| 95 | #else | 105 | #else |
| 96 | #ifdef _WIN64 | 106 | #ifdef _WIN64 |
| @@ -166,7 +176,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 69 unmodified lines | |||
| 166 | 176 | ||
| 167 | /* relocate code. Return -1 on error, required size if ptr is NULL, | 177 | /* relocate code. Return -1 on error, required size if ptr is NULL, |
| 168 | otherwise copy code into buffer passed by the caller */ | 178 | otherwise copy code into buffer passed by the caller */ |
| 169 | static int tcc_relocate_ex(TCCState *s1, void *ptr) | 179 | static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff) |
| 170 | { | 180 | { |
| 171 | Section *s; | 181 | Section *s; |
| 172 | unsigned offset, length, fill, i, k; | 182 | unsigned offset, length, fill, i, k; |
| @@ -199,7 +209,12 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) · 26 unmodified lines | |||
| 199 | if (k != !(s->sh_flags & SHF_EXECINSTR)) | 209 | if (k != !(s->sh_flags & SHF_EXECINSTR)) |
| 200 | continue; | 210 | continue; |
| 201 | offset += fill; | 211 | offset += fill; |
| 202 | s->sh_addr = mem ? mem + offset : 0; | 212 | if (!mem) |
| 213 | s->sh_addr = 0; | ||
| 214 | else if (s->sh_flags & SHF_EXECINSTR) | ||
| 215 | s->sh_addr = mem + offset + ptr_diff; | ||
| 216 | else | ||
| 217 | s->sh_addr = mem + offset; | ||
| 203 | #if 0 | 218 | #if 0 |
| 204 | if (mem) | 219 | if (mem) |
| 205 | printf("%-16s +%02lx %p %04x\n", | 220 | printf("%-16s +%02lx %p %04x\n", |
| @@ -242,13 +257,15 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) · 36 unmodified lines | |||
| 242 | continue; | 257 | continue; |
| 243 | length = s->data_offset; | 258 | length = s->data_offset; |
| 244 | ptr = (void*)s->sh_addr; | 259 | ptr = (void*)s->sh_addr; |
| 260 | if (s->sh_flags & SHF_EXECINSTR) | ||
| 261 | ptr = (char*)ptr - ptr_diff; | ||
| 245 | if (NULL == s->data || s->sh_type == SHT_NOBITS) | 262 | if (NULL == s->data || s->sh_type == SHT_NOBITS) |
| 246 | memset(ptr, 0, length); | 263 | memset(ptr, 0, length); |
| 247 | else | 264 | else |
| 248 | memcpy(ptr, s->data, length); | 265 | memcpy(ptr, s->data, length); |
| 249 | /* mark executable sections as executable in memory */ | 266 | /* mark executable sections as executable in memory */ |
| 250 | if (s->sh_flags & SHF_EXECINSTR) | 267 | if (s->sh_flags & SHF_EXECINSTR) |
| 251 | set_pages_executable(ptr, length); | 268 | set_pages_executable((char*)ptr + ptr_diff, length); |
| 252 | } | 269 | } |
| 253 | return 0; | 270 | return 0; |
| 254 | } | 271 | } |
| @@ -263,15 +280,17 @@ static void set_pages_executable(void *ptr, unsigned long length) · 8 unmodified lines | |||
| 263 | VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); | 280 | VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); |
| 264 | #else | 281 | #else |
| 265 | void __clear_cache(void *beginning, void *end); | 282 | void __clear_cache(void *beginning, void *end); |
| 283 | # ifndef HAVE_SELINUX | ||
| 266 | addr_t start, end; | 284 | addr_t start, end; |
| 267 | #ifndef PAGESIZE | 285 | # ifndef PAGESIZE |
| 268 | # define PAGESIZE 4096 | 286 | # define PAGESIZE 4096 |
| 269 | #endif | 287 | # endif |
| 270 | start = (addr_t)ptr & ~(PAGESIZE - 1); | 288 | start = (addr_t)ptr & ~(PAGESIZE - 1); |
| 271 | end = (addr_t)ptr + length; | 289 | end = (addr_t)ptr + length; |
| 272 | end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); | 290 | end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); |
| 273 | if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC)) | 291 | if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC)) |
| 274 | tcc_error("mprotect failed: did you mean to configure --with-selinux?"); | 292 | tcc_error("mprotect failed: did you mean to configure --with-selinux?"); |
| 293 | # endif | ||
| 275 | # if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 | 294 | # if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 |
| 276 | __clear_cache(ptr, (char *)ptr + length); | 295 | __clear_cache(ptr, (char *)ptr + length); |
| 277 | # endif | 296 | # endif |
| @@ -120,6 +120,8 @@ · 119 unmodified lines | |||
| 120 | DEF(TOK_FASTCALL1, "fastcall") | 120 | DEF(TOK_FASTCALL1, "fastcall") |
| 121 | DEF(TOK_FASTCALL2, "__fastcall") | 121 | DEF(TOK_FASTCALL2, "__fastcall") |
| 122 | DEF(TOK_FASTCALL3, "__fastcall__") | 122 | DEF(TOK_FASTCALL3, "__fastcall__") |
| 123 | DEF(TOK_REGPARM1, "regparm") | ||
| 124 | DEF(TOK_REGPARM2, "__regparm__") | ||
| 123 | 125 | ||
| 124 | DEF(TOK_MODE, "__mode__") | 126 | DEF(TOK_MODE, "__mode__") |
| 125 | DEF(TOK_MODE_QI, "__QI__") | 127 | DEF(TOK_MODE_QI, "__QI__") |
| @@ -134,23 +136,19 @@ · 8 unmodified lines | |||
| 134 | DEF(TOK_NORETURN2, "__noreturn__") | 136 | DEF(TOK_NORETURN2, "__noreturn__") |
| 135 | DEF(TOK_VISIBILITY1, "visibility") | 137 | DEF(TOK_VISIBILITY1, "visibility") |
| 136 | DEF(TOK_VISIBILITY2, "__visibility__") | 138 | DEF(TOK_VISIBILITY2, "__visibility__") |
| 139 | |||
| 137 | DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") | 140 | DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") |
| 138 | DEF(TOK_builtin_choose_expr, "__builtin_choose_expr") | 141 | DEF(TOK_builtin_choose_expr, "__builtin_choose_expr") |
| 139 | DEF(TOK_builtin_constant_p, "__builtin_constant_p") | 142 | DEF(TOK_builtin_constant_p, "__builtin_constant_p") |
| 140 | DEF(TOK_builtin_frame_address, "__builtin_frame_address") | 143 | DEF(TOK_builtin_frame_address, "__builtin_frame_address") |
| 141 | DEF(TOK_builtin_return_address, "__builtin_return_address") | 144 | DEF(TOK_builtin_return_address, "__builtin_return_address") |
| 142 | DEF(TOK_builtin_expect, "__builtin_expect") | 145 | DEF(TOK_builtin_expect, "__builtin_expect") |
| 143 | #ifdef TCC_TARGET_X86_64 | 146 | /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/ |
| 144 | #ifdef TCC_TARGET_PE | 147 | #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64 |
| 145 | DEF(TOK_builtin_va_start, "__builtin_va_start") | 148 | DEF(TOK_builtin_va_start, "__builtin_va_start") |
| 146 | #else | 149 | #elif defined TCC_TARGET_X86_64 |
| 147 | DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types") | 150 | DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types") |
| 148 | #endif | 151 | #elif defined TCC_TARGET_ARM64 |
| 149 | #endif | ||
| 150 | DEF(TOK_REGPARM1, "regparm") | ||
| 151 | DEF(TOK_REGPARM2, "__regparm__") | ||
| 152 | |||
| 153 | #ifdef TCC_TARGET_ARM64 | ||
| 154 | DEF(TOK___va_start, "__va_start") | 152 | DEF(TOK___va_start, "__va_start") |
| 155 | DEF(TOK___va_arg, "__va_arg") | 153 | DEF(TOK___va_arg, "__va_arg") |
| 156 | #endif | 154 | #endif |
| @@ -234,8 +234,12 @@ vla_test-run: vla_test$(EXESUF) · 233 unmodified lines | |||
| 234 | cross-test : | 234 | cross-test : |
| 235 | @echo ------------ $@ ------------ | 235 | @echo ------------ $@ ------------ |
| 236 | $(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" | 236 | $(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" |
| 237 | $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok" | ||
| 237 | $(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" | 238 | $(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" |
| 239 | $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok" | ||
| 238 | $(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" | 240 | $(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" |
| 241 | $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/examples/ex3.c && echo "ok" | ||
| 242 | $(TOP)/arm64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" | ||
| 239 | $(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" | 243 | $(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" |
| 240 | $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok" | 244 | $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok" |
| 241 | $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok" | 245 | $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok" |
| @@ -1,3 +1,2 @@ | |||
| 1 | # `modelist' label. Each video mode record looks like: | ||
| 2 | .text | 1 | .text |
| 3 | endtext: | 2 | endtext: |
| @@ -12,7 +12,7 @@ return n(A)n(++)n(+)n(+)n(B); · 11 unmodified lines | |||
| 12 | return n(0x1E)n(-1); | 12 | return n(0x1E)n(-1); |
| 13 | 13 | ||
| 14 | // unlike gcc but correct | 14 | // unlike gcc but correct |
| 15 | XXX: return n(x)+n(x)-n(1)+n(1)-2; | 15 | // XXX: return n(x)+n(x)-n(1)+n(1)-2; |
| 16 | 16 | ||
| 17 | // unlike gcc, but cannot appear in valid C | 17 | // unlike gcc, but cannot appear in valid C |
| 18 | XXX: return n(x)n(x)n(1)n(2)n(x); | 18 | // XXX: return n(x)n(x)n(1)n(2)n(x); |
| @@ -3,5 +3,3 @@ return A+++B; · 2 unmodified lines | |||
| 3 | return A+ ++B; | 3 | return A+ ++B; |
| 4 | return A+++ +B; | 4 | return A+++ +B; |
| 5 | return 0x1E -1; | 5 | return 0x1E -1; |
| 6 | XXX: return x+x-1 +1 -2; | ||
| 7 | XXX: return x x 1 2 x; | ||
| @@ -12,7 +12,7 @@ TESTS = $(call files,c) $(call files,S) · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | all test : $(sort $(TESTS)) | 13 | all test : $(sort $(TESTS)) |
| 14 | 14 | ||
| 15 | DIFF_OPTS = -Nu -b -B -I "^\#" | 15 | DIFF_OPTS = -Nu -b -B |
| 16 | 16 | ||
| 17 | # Filter source directory in warnings/errors (out-of-tree builds) | 17 | # Filter source directory in warnings/errors (out-of-tree builds) |
| 18 | FILTER = 2>&1 | sed 's,$(SRC)/,,g' | 18 | FILTER = 2>&1 | sed 's,$(SRC)/,,g' |
| @@ -40,7 +40,7 @@ clean: · 21 unmodified lines | |||
| 40 | rm -f *.output | 40 | rm -f *.output |
| 41 | 41 | ||
| 42 | 02.test : DIFF_OPTS += -w | 42 | 02.test : DIFF_OPTS += -w |
| 43 | 15.test : DIFF_OPTS += -I"^XXX:" | 43 | # 15.test : DIFF_OPTS += -I"^XXX:" |
| 44 | 44 | ||
| 45 | # diff options: | 45 | # diff options: |
| 46 | # -b ighore space changes | 46 | # -b ighore space changes |
| @@ -3235,6 +3235,7 @@ void asm_local_statics (void) · 3234 unmodified lines | |||
| 3235 | } | 3235 | } |
| 3236 | #endif | 3236 | #endif |
| 3237 | 3237 | ||
| 3238 | static | ||
| 3238 | unsigned int set; | 3239 | unsigned int set; |
| 3239 | 3240 | ||
| 3240 | void fancy_copy (unsigned *in, unsigned *out) | 3241 | void fancy_copy (unsigned *in, unsigned *out) |
| @@ -3247,7 +3248,7 @@ void fancy_copy2 (unsigned *in, unsigned *out) · 6 unmodified lines | |||
| 3247 | asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); | 3248 | asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); |
| 3248 | } | 3249 | } |
| 3249 | 3250 | ||
| 3250 | #ifdef __x86_64__ | 3251 | #if defined __x86_64__ && !defined _WIN64 |
| 3251 | void clobber_r12(void) | 3252 | void clobber_r12(void) |
| 3252 | { | 3253 | { |
| 3253 | asm volatile("mov $1, %%r12" ::: "r12"); | 3254 | asm volatile("mov $1, %%r12" ::: "r12"); |
| @@ -3256,7 +3257,7 @@ void clobber_r12(void) · 2 unmodified lines | |||
| 3256 | 3257 | ||
| 3257 | void test_high_clobbers(void) | 3258 | void test_high_clobbers(void) |
| 3258 | { | 3259 | { |
| 3259 | #ifdef __x86_64__ | 3260 | #if defined __x86_64__ && !defined _WIN64 |
| 3260 | register long val asm("r12"); | 3261 | register long val asm("r12"); |
| 3261 | long val2; | 3262 | long val2; |
| 3262 | /* This tests if asm clobbers correctly save/restore callee saved | 3263 | /* This tests if asm clobbers correctly save/restore callee saved |
| @@ -3265,11 +3266,9 @@ void test_high_clobbers(void) · 2 unmodified lines | |||
| 3265 | correctly capture the data flow, but good enough for us. */ | 3266 | correctly capture the data flow, but good enough for us. */ |
| 3266 | asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory"); | 3267 | asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory"); |
| 3267 | clobber_r12(); | 3268 | clobber_r12(); |
| 3268 | #ifndef _WIN64 | ||
| 3269 | asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory"); | 3269 | asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory"); |
| 3270 | printf("asmhc: 0x%x\n", val2); | 3270 | printf("asmhc: 0x%x\n", val2); |
| 3271 | #endif | 3271 | #endif |
| 3272 | #endif | ||
| 3273 | } | 3272 | } |
| 3274 | 3273 | ||
| 3275 | static long cpu_number; | 3274 | static long cpu_number; |
| @@ -70,7 +70,7 @@ · 69 unmodified lines | |||
| 70 | { | 70 | { |
| 71 | struct M P __s { | 71 | struct M P __s { |
| 72 | int a; | 72 | int a; |
| 73 | char b; | 73 | signed char b; |
| 74 | int x : 12, y : 4, : 0, : 4, z : 3; | 74 | int x : 12, y : 4, : 0, : 4, z : 3; |
| 75 | char d; | 75 | char d; |
| 76 | }; | 76 | }; |
| @@ -78,7 +78,7 @@ te1:; · 77 unmodified lines | |||
| 78 | tl += &&te1 - &&ts1; | 78 | tl += &&te1 - &&ts1; |
| 79 | printf("size of data/text:\n %s/%s\n", | 79 | printf("size of data/text:\n %s/%s\n", |
| 80 | dl ? "non-zero":"zero", tl ? "non-zero":"zero"); | 80 | dl ? "non-zero":"zero", tl ? "non-zero":"zero"); |
| 81 | printf("# %d/%d\n", dl, tl); | 81 | /*printf("# %d/%d\n", dl, tl);*/ |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | #endif | 84 | #endif |
| @@ -17,9 +17,7 @@ data: · 16 unmodified lines | |||
| 17 | 333 44 555555 6 7 | 17 | 333 44 555555 6 7 |
| 18 | size of data/text: | 18 | size of data/text: |
| 19 | non-zero/non-zero | 19 | non-zero/non-zero |
| 20 | # 111/193 | ||
| 21 | 20 | ||
| 22 | [test_data_suppression_on] | 21 | [test_data_suppression_on] |
| 23 | size of data/text: | 22 | size of data/text: |
| 24 | zero/zero | 23 | zero/zero |
| 25 | # 0/0 | ||
| @@ -70,7 +70,7 @@ all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ; · 69 unmodified lines | |||
| 70 | T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS) | 70 | T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS) |
| 71 | T2 = $(TCC) $(FLAGS) -run $< $(ARGS) | 71 | T2 = $(TCC) $(FLAGS) -run $< $(ARGS) |
| 72 | T3 = $(FILTER) >$*.output 2>&1 || true \ | 72 | T3 = $(FILTER) >$*.output 2>&1 || true \ |
| 73 | && diff -Nbu -I "^\#" $(filter %.expect,$^) $*.output \ | 73 | && diff -Nbu $(filter %.expect,$^) $*.output \ |
| 74 | && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS)) | 74 | && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS)) |
| 75 | 75 | ||
| 76 | # run single test and update .expect file, e.g. "make tests2.37+" | 76 | # run single test and update .expect file, e.g. "make tests2.37+" |
| @@ -1,148 +0,0 @@ | |||
| 1 | # | ||
| 2 | # This Makefile builds native Windows tcc for both 32 and 64 bits generator. | ||
| 3 | # It requires Cygwin 64 and gcc to bootstrap a first tcc version which is used | ||
| 4 | # by a second stage to compile tcc it self. | ||
| 5 | # Generated binaries do not require cygwin to run. | ||
| 6 | # You can launch 'tarball' target to build a tar.gz you can install on any | ||
| 7 | # Windows machines. | ||
| 8 | |||
| 9 | CPU = $(shell if `gcc -v 2>&1 | grep Target | grep -q x86_64`; then echo 64; else echo 32; fi) | ||
| 10 | VERSION = $(shell cat ../VERSION) | ||
| 11 | BOOTCC = gcc | ||
| 12 | CFLAGS = -s -static -fno-strict-aliasing -Wno-incompatible-pointer-types -DTCC_TARGET_PE | ||
| 13 | #WINPWD = `cygpath --mixed $(PWD)` | ||
| 14 | #@echo "#define CONFIG_TCCDIR \"$(WINPWD)\"" | ||
| 15 | |||
| 16 | ifeq ($(CPU), 64) | ||
| 17 | NATIVE = -m$(CPU) -DTCC_TARGET_X86_64 | ||
| 18 | ARCH = x86_64 | ||
| 19 | else | ||
| 20 | NATIVE = -m$(CPU) -DTCC_TARGET_I386 | ||
| 21 | ARCH = i386 | ||
| 22 | endif | ||
| 23 | |||
| 24 | TARGET = $(CPU) | ||
| 25 | |||
| 26 | ifeq ($(TARGET), 64) | ||
| 27 | TFLAGS = -m$(TARGET) -DTCC_TARGET_X86_64 | ||
| 28 | TARCH = x86_64 | ||
| 29 | else | ||
| 30 | TFLAGS = -m$(TARGET) -DTCC_TARGET_I386 | ||
| 31 | TARCH = i386 | ||
| 32 | endif | ||
| 33 | |||
| 34 | all: pre bootstrap libs rebuild | ||
| 35 | @chmod 775 *.exe | ||
| 36 | @ls -ls *.exe | ||
| 37 | |||
| 38 | pre: | ||
| 39 | @echo ARCH=$(TARCH) 1> ../config.mak | ||
| 40 | @echo TARGETOS=Windows 1>> ../config.mak | ||
| 41 | @echo CONFIG_WIN32=yes 1>> ../config.mak | ||
| 42 | @echo TOPSRC=$$\(TOP\) 1>> ../config.mak | ||
| 43 | @echo "#define TCC_VERSION \"$(VERSION)\"" 1>../config.h | ||
| 44 | @echo "#ifdef TCC_TARGET_X86_64" 1>>../config.h | ||
| 45 | @echo "#define TCC_LIBTCC1 \"libtcc1-64.a\"" 1>>../config.h | ||
| 46 | @echo "#else" 1>>../config.h | ||
| 47 | @echo "#define TCC_LIBTCC1 \"libtcc1-32.a\"" 1>>../config.h | ||
| 48 | @echo "#endif" 1>>../config.h | ||
| 49 | @echo @set VERSION $(VERSION) 1>../config.texi | ||
| 50 | @rm -f *tcc.exe tiny_*.exe *tcc.dll lib/*.a | ||
| 51 | @rm -r -f libtcc doc | ||
| 52 | @mkdir libtcc | ||
| 53 | @mkdir doc | ||
| 54 | @cp ../include/*.h include | ||
| 55 | @cp ../tcclib.h include | ||
| 56 | @cp ../libtcc.h include | ||
| 57 | @cp tcc-win32.txt doc | ||
| 58 | @cp ../tests/libtcc_test.c examples | ||
| 59 | |||
| 60 | PHONY += pre | ||
| 61 | |||
| 62 | bootstrap: | ||
| 63 | @echo Bootstrapping 32bits and 64bits tools with $(BOOTCC) -m$(CPU) | ||
| 64 | @$(BOOTCC) $(CFLAGS) -DTCC_TARGET_I386 -o i386-win32-tcc.exe ../tcc.c | ||
| 65 | @$(BOOTCC) $(CFLAGS) -DTCC_TARGET_X86_64 -o x86_64-win32-tcc.exe ../tcc.c | ||
| 66 | @$(BOOTCC) $(CFLAGS) $(NATIVE) -o tcc.exe ../tcc.c | ||
| 67 | @$(BOOTCC) $(CFLAGS) $(NATIVE) -DLIBTCC_AS_DLL -o libtcc.dll -shared ../libtcc.c | ||
| 68 | |||
| 69 | PHONY += bootstrap | ||
| 70 | |||
| 71 | lib/libtcc1-32.a: | ||
| 72 | @echo Building $*.a with tcc -m32 | ||
| 73 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/libtcc1.c | ||
| 74 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/alloca86.S | ||
| 75 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/alloca86-bt.S | ||
| 76 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/crt1.c | ||
| 77 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/crt1w.c | ||
| 78 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/wincrt1.c | ||
| 79 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/wincrt1w.c | ||
| 80 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/dllcrt1.c | ||
| 81 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/dllmain.c | ||
| 82 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/chkstk.S | ||
| 83 | @./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 | ||
| 84 | @rm *.o | ||
| 85 | |||
| 86 | lib/libtcc1-64.a: | ||
| 87 | @echo Building $*.a with tcc -m64 | ||
| 88 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/libtcc1.c | ||
| 89 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/alloca86_64.S | ||
| 90 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/alloca86_64-bt.S | ||
| 91 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/crt1.c | ||
| 92 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/crt1w.c | ||
| 93 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/wincrt1.c | ||
| 94 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/wincrt1w.c | ||
| 95 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/dllcrt1.c | ||
| 96 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/dllmain.c | ||
| 97 | @./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/chkstk.S | ||
| 98 | @./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 | ||
| 99 | @rm *.o | ||
| 100 | |||
| 101 | libs: lib/libtcc1-32.a lib/libtcc1-64.a | ||
| 102 | |||
| 103 | PHONY += libs | ||
| 104 | |||
| 105 | rebuild: | ||
| 106 | @echo Rebuild using tcc itself - default $(TARGET)bits | ||
| 107 | @./$(TARCH)-win32-tcc -O2 -B. $(TFLAGS) -DTCC_TARGET_PE -o tcc.exe ../tcc.c | ||
| 108 | @./tcc -O2 -B. $(TFLAGS) -DTCC_TARGET_PE -DLIBTCC_AS_DLL -o libtcc.dll -shared ../libtcc.c | ||
| 109 | @./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -o tmp-tcc.exe ../tcc.c && mv tmp-tcc.exe i386-win32-tcc.exe | ||
| 110 | @./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 | ||
| 111 | |||
| 112 | PHONY += rebuild | ||
| 113 | |||
| 114 | test: | ||
| 115 | @(cd ../tests; $(MAKE) -k TCC=$(PWD)/tcc hello-exe hello-run) | ||
| 116 | @(cd ../tests; $(MAKE) -k TCC=$(PWD)/tcc vla_test-run tests2-dir pp-dir) | ||
| 117 | ifeq ($(CPU), 64) | ||
| 118 | @(cd ../tests; $(MAKE) -k TCC=$(PWD)/i386-win32-tcc hello-exe hello-run) | ||
| 119 | @(cd ../tests; $(MAKE) -k TCC=$(PWD)/i386-win32-tcc vla_test-run tests2-dir pp-dir) | ||
| 120 | endif | ||
| 121 | |||
| 122 | PHONY += test | ||
| 123 | |||
| 124 | TARNAME = tcc-$(VERSION)-$(ARCH)-win32 | ||
| 125 | |||
| 126 | tarball: | ||
| 127 | @rm -r -f $(TARNAME) | ||
| 128 | @mkdir $(TARNAME) | ||
| 129 | @cp -r doc $(TARNAME) | ||
| 130 | @cp -r examples $(TARNAME) | ||
| 131 | @cp -r include $(TARNAME) | ||
| 132 | @cp -r lib $(TARNAME) | ||
| 133 | @cp -r libtcc $(TARNAME) | ||
| 134 | @cp -r build-tcc.bat $(TARNAME) | ||
| 135 | @cp -r i386-win32-tcc.exe $(TARNAME) | ||
| 136 | @cp -r libtcc.def $(TARNAME) | ||
| 137 | @cp -r libtcc.dll $(TARNAME) | ||
| 138 | @cp -r Makefile $(TARNAME) | ||
| 139 | @cp -r tcc.exe $(TARNAME) | ||
| 140 | @cp -r tcc-win32.txt $(TARNAME) | ||
| 141 | @cp -r x86_64-win32-tcc.exe $(TARNAME) | ||
| 142 | @tar czf $(TARNAME).tar.gz $(TARNAME) | ||
| 143 | @rm -r -f $(TARNAME) | ||
| 144 | |||
| 145 | PHONY += tarball | ||
| 146 | |||
| 147 | clean: | ||
| 148 | rm -f *.o *.exe *.dll lib/*.a *.pdb *.obj *.exp *.def *.lib | ||
| @@ -4,13 +4,31 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | @echo off | 5 | @echo off |
| 6 | setlocal | 6 | setlocal |
| 7 | 7 | if (%1)==(-clean) goto :cleanup | |
| 8 | set CC=gcc -Os -s -static | 8 | set CC=gcc |
| 9 | set /p VERSION= < ..\VERSION | 9 | set /p VERSION= < ..\VERSION |
| 10 | set INST= | 10 | set INST= |
| 11 | set BIN= | ||
| 11 | set DOC=no | 12 | set DOC=no |
| 13 | set EXES_ONLY=no | ||
| 12 | goto :a0 | 14 | goto :a0 |
| 13 | 15 | :a2 | |
| 16 | shift | ||
| 17 | :a3 | ||
| 18 | shift | ||
| 19 | :a0 | ||
| 20 | if not (%1)==(-c) goto :a1 | ||
| 21 | set CC=%~2 | ||
| 22 | if (%2)==(cl) set CC=@call :cl | ||
| 23 | goto :a2 | ||
| 24 | :a1 | ||
| 25 | if (%1)==(-t) set T=%2&& goto :a2 | ||
| 26 | if (%1)==(-v) set VERSION=%~2&& goto :a2 | ||
| 27 | if (%1)==(-i) set INST=%2&& goto :a2 | ||
| 28 | if (%1)==(-b) set BIN=%2&& goto :a2 | ||
| 29 | if (%1)==(-d) set DOC=yes&& goto :a3 | ||
| 30 | if (%1)==(-x) set EXES_ONLY=yes&& goto :a3 | ||
| 31 | if (%1)==() goto :p1 | ||
| 14 | :usage | 32 | :usage |
| 15 | echo usage: build-tcc.bat [ options ... ] | 33 | echo usage: build-tcc.bat [ options ... ] |
| 16 | echo options: | 34 | echo options: |
| @@ -18,10 +36,35 @@ echo -c prog use prog (gcc/tcc/cl) to compile tcc · 1 unmodified line | |||
| 18 | echo -c "prog options" use prog with options to compile tcc | 36 | echo -c "prog options" use prog with options to compile tcc |
| 19 | echo -t 32/64 force 32/64 bit default target | 37 | echo -t 32/64 force 32/64 bit default target |
| 20 | echo -v "version" set tcc version | 38 | echo -v "version" set tcc version |
| 21 | echo -i dir install tcc into dir | 39 | echo -i tccdir install tcc into tccdir |
| 40 | echo -b bindir optionally install binaries into bindir elsewhere | ||
| 22 | echo -d create tcc-doc.html too (needs makeinfo) | 41 | echo -d create tcc-doc.html too (needs makeinfo) |
| 42 | echo -x just create the executables | ||
| 43 | echo -clean delete all previously produced files and directories | ||
| 23 | exit /B 1 | 44 | exit /B 1 |
| 24 | 45 | ||
| 46 | @rem ------------------------------------------------------ | ||
| 47 | @rem sub-routines | ||
| 48 | |||
| 49 | :cleanup | ||
| 50 | set LOG=echo | ||
| 51 | %LOG% removing files: | ||
| 52 | for %%f in (*tcc.exe libtcc.dll lib\*.a) do call :del_file %%f | ||
| 53 | for %%f in (..\config.h ..\config.texi) do call :del_file %%f | ||
| 54 | for %%f in (include\*.h) do @if exist ..\%%f call :del_file %%f | ||
| 55 | for %%f in (include\tcclib.h examples\libtcc_test.c) do call :del_file %%f | ||
| 56 | for %%f in (*.o *.obj *.def *.pdb *.lib *.exp *.ilk) do call :del_file %%f | ||
| 57 | %LOG% removing directories: | ||
| 58 | for %%f in (doc libtcc) do call :del_dir %%f | ||
| 59 | %LOG% done. | ||
| 60 | exit /B 0 | ||
| 61 | :del_file | ||
| 62 | if exist %1 del %1 && %LOG% %1 | ||
| 63 | exit /B 0 | ||
| 64 | :del_dir | ||
| 65 | if exist %1 rmdir /Q/S %1 && %LOG% %1 | ||
| 66 | exit /B 0 | ||
| 67 | |||
| 25 | :cl | 68 | :cl |
| 26 | @echo off | 69 | @echo off |
| 27 | set CMD=cl | 70 | set CMD=cl |
| @@ -37,52 +80,16 @@ echo on · 9 unmodified lines | |||
| 37 | %CMD% -O1 -W2 -Zi -MT -GS- -nologo -link -opt:ref,icf | 80 | %CMD% -O1 -W2 -Zi -MT -GS- -nologo -link -opt:ref,icf |
| 38 | @exit /B %ERRORLEVEL% | 81 | @exit /B %ERRORLEVEL% |
| 39 | 82 | ||
| 40 | :a2 | 83 | @rem ------------------------------------------------------ |
| 41 | shift | 84 | @rem main program |
| 42 | :a1 | ||
| 43 | shift | ||
| 44 | :a0 | ||
| 45 | if not (%1)==(-c) goto :a3 | ||
| 46 | set CC=%~2 | ||
| 47 | if (%2)==(cl) set CC=@call :cl | ||
| 48 | goto :a2 | ||
| 49 | :a3 | ||
| 50 | if not (%1)==(-t) goto :a4 | ||
| 51 | set T=%2 | ||
| 52 | goto :a2 | ||
| 53 | :a4 | ||
| 54 | if not (%1)==(-v) goto :a5 | ||
| 55 | set VERSION=%~2 | ||
| 56 | goto :a2 | ||
| 57 | :a5 | ||
| 58 | if not (%1)==(-i) goto :a6 | ||
| 59 | set INST=%2 | ||
| 60 | goto :a2 | ||
| 61 | :a6 | ||
| 62 | if not (%1)==(-d) goto :a7 | ||
| 63 | set DOC=yes | ||
| 64 | goto :a1 | ||
| 65 | :a7 | ||
| 66 | if not (%1)==() goto :usage | ||
| 67 | |||
| 68 | if not "%CC%"=="@call :cl" goto :p1 | ||
| 69 | set VSCOMNTOOLS=%VS150COMNTOOLS% | ||
| 70 | if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS140COMNTOOLS% | ||
| 71 | if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS130COMNTOOLS% | ||
| 72 | if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS120COMNTOOLS% | ||
| 73 | if %T%_==32_ set CLVARS="%VSCOMNTOOLS%..\..\VC\bin\vcvars32.bat" | ||
| 74 | if %T%_==64_ set CLVARS="%VSCOMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat" | ||
| 75 | if %T%_==_ set T=32& if %Platform%_==X64_ set T=64 | ||
| 76 | if %CLVARS%_==_ goto :p1 | ||
| 77 | if exist %CLVARS% call %CLVARS% | ||
| 78 | :p1 | ||
| 79 | 85 | ||
| 86 | :p1 | ||
| 80 | if not %T%_==_ goto :p2 | 87 | if not %T%_==_ goto :p2 |
| 81 | set T=32 | 88 | set T=32 |
| 82 | if %PROCESSOR_ARCHITECTURE%_==AMD64_ set T=64 | 89 | if %PROCESSOR_ARCHITECTURE%_==AMD64_ set T=64 |
| 83 | if %PROCESSOR_ARCHITEW6432%_==AMD64_ set T=64 | 90 | if %PROCESSOR_ARCHITEW6432%_==AMD64_ set T=64 |
| 84 | :p2 | 91 | :p2 |
| 85 | 92 | if "%CC:~-3%"=="gcc" set CC=%CC% -Os -s -static | |
| 86 | set D32=-DTCC_TARGET_PE -DTCC_TARGET_I386 | 93 | set D32=-DTCC_TARGET_PE -DTCC_TARGET_I386 |
| 87 | set D64=-DTCC_TARGET_PE -DTCC_TARGET_X86_64 | 94 | set D64=-DTCC_TARGET_PE -DTCC_TARGET_X86_64 |
| 88 | set P32=i386-win32 | 95 | set P32=i386-win32 |
| @@ -91,13 +98,14 @@ if %T%==64 goto :t64 · 2 unmodified lines | |||
| 91 | set D=%D32% | 98 | set D=%D32% |
| 92 | set DX=%D64% | 99 | set DX=%D64% |
| 93 | set PX=%P64% | 100 | set PX=%P64% |
| 94 | goto :t96 | 101 | goto :p3 |
| 95 | :t64 | 102 | :t64 |
| 96 | set D=%D64% | 103 | set D=%D64% |
| 97 | set DX=%D32% | 104 | set DX=%D32% |
| 98 | set PX=%P32% | 105 | set PX=%P32% |
| 99 | :t96 | 106 | goto :p3 |
| 100 | 107 | ||
| 108 | :p3 | ||
| 101 | @echo on | 109 | @echo on |
| 102 | 110 | ||
| 103 | :config.h | 111 | :config.h |
| @@ -116,7 +124,7 @@ for %%f in (*tcc.exe *tcc.dll) do @del %%f · 12 unmodified lines | |||
| 116 | %CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0" | 124 | %CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0" |
| 117 | %CC% -o %PX%-tcc.exe ..\tcc.c %DX% | 125 | %CC% -o %PX%-tcc.exe ..\tcc.c %DX% |
| 118 | 126 | ||
| 119 | @if (%TCC_FILES%)==(no) goto :files-done | 127 | @if (%EXES_ONLY%)==(yes) goto :files-done |
| 120 | 128 | ||
| 121 | if not exist libtcc mkdir libtcc | 129 | if not exist libtcc mkdir libtcc |
| 122 | if not exist doc mkdir doc | 130 | if not exist doc mkdir doc |
| @@ -170,8 +178,11 @@ for %%f in (*.o *.def) do @del %%f · 47 unmodified lines | |||
| 170 | :copy-install | 178 | :copy-install |
| 171 | @if (%INST%)==() goto :the_end | 179 | @if (%INST%)==() goto :the_end |
| 172 | if not exist %INST% mkdir %INST% | 180 | if not exist %INST% mkdir %INST% |
| 181 | @if (%BIN%)==() set BIN=%INST% | ||
| 182 | if not exist %BIN% mkdir %BIN% | ||
| 183 | for %%f in (*tcc.exe *tcc.dll) do @copy>nul %%f %BIN%\%%f | ||
| 173 | @if not exist %INST%\lib mkdir %INST%\lib | 184 | @if not exist %INST%\lib mkdir %INST%\lib |
| 174 | for %%f in (*tcc.exe *tcc.dll lib\*.a lib\*.def) do @copy>nul %%f %INST%\%%f | 185 | for %%f in (lib\*.a lib\*.def) do @copy>nul %%f %INST%\%%f |
| 175 | for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %INST%\%%f | 186 | for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %INST%\%%f |
| 176 | 187 | ||
| 177 | :the_end | 188 | :the_end |
| @@ -16,11 +16,6 @@ · 15 unmodified lines | |||
| 16 | #define _PC_53 0x00010000 // 53 bits | 16 | #define _PC_53 0x00010000 // 53 bits |
| 17 | #define _PC_64 0x00000000 // 64 bits | 17 | #define _PC_64 0x00000000 // 64 bits |
| 18 | 18 | ||
| 19 | typedef struct | ||
| 20 | { | ||
| 21 | int newmode; | ||
| 22 | } _startupinfo; | ||
| 23 | |||
| 24 | #ifdef _UNICODE | 19 | #ifdef _UNICODE |
| 25 | #define __tgetmainargs __wgetmainargs | 20 | #define __tgetmainargs __wgetmainargs |
| 26 | #define _tstart _wstart | 21 | #define _tstart _wstart |
| @@ -33,6 +28,7 @@ typedef struct · 6 unmodified lines | |||
| 33 | #define _runtmain _runmain | 28 | #define _runtmain _runmain |
| 34 | #endif | 29 | #endif |
| 35 | 30 | ||
| 31 | typedef struct { int newmode; } _startupinfo; | ||
| 36 | int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); | 32 | int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); |
| 37 | void __cdecl __set_app_type(int apptype); | 33 | void __cdecl __set_app_type(int apptype); |
| 38 | unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); | 34 | unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); |
| @@ -44,23 +40,19 @@ int _dowildcard; · 5 unmodified lines | |||
| 44 | void _tstart(void) | 40 | void _tstart(void) |
| 45 | { | 41 | { |
| 46 | __TRY__ | 42 | __TRY__ |
| 47 | int ret; | 43 | _startupinfo start_info = {0}; |
| 48 | _startupinfo start_info; | ||
| 49 | 44 | ||
| 50 | // Sets the current application type | 45 | // Sets the current application type |
| 51 | __set_app_type(_CONSOLE_APP); | 46 | __set_app_type(_CONSOLE_APP); |
| 52 | 47 | ||
| 53 | // Set default FP precision to 53 bits (8-byte double) | 48 | // Set default FP precision to 53 bits (8-byte double) |
| 54 | // _MCW_PC (Precision control) is not supported on | 49 | // _MCW_PC (Precision control) is not supported on ARM |
| 55 | // the ARM and x64 architectures | 50 | #if defined __i386__ || defined __x86_64__ |
| 56 | #ifdef __i386 | ||
| 57 | _controlfp(_PC_53, _MCW_PC); | 51 | _controlfp(_PC_53, _MCW_PC); |
| 58 | #endif | 52 | #endif |
| 59 | 53 | ||
| 60 | start_info.newmode = 0; | ||
| 61 | __tgetmainargs( &__argc, &__targv, &_tenviron, _dowildcard, &start_info); | 54 | __tgetmainargs( &__argc, &__targv, &_tenviron, _dowildcard, &start_info); |
| 62 | ret = _tmain(__argc, __targv, _tenviron); | 55 | exit(_tmain(__argc, __targv, _tenviron)); |
| 63 | exit(ret); | ||
| 64 | } | 56 | } |
| 65 | 57 | ||
| 66 | int _runtmain(int argc, /* as tcc passed in */ char **argv) | 58 | int _runtmain(int argc, /* as tcc passed in */ char **argv) |
| @@ -78,8 +70,7 @@ int _runtmain(int argc, /* as tcc passed in */ char **argv) · 11 unmodified lines | |||
| 78 | __argc = argc; | 70 | __argc = argc; |
| 79 | __targv = argv; | 71 | __targv = argv; |
| 80 | #endif | 72 | #endif |
| 81 | 73 | #if defined __i386__ || defined __x86_64__ | |
| 82 | #ifdef __i386 | ||
| 83 | _controlfp(_PC_53, _MCW_PC); | 74 | _controlfp(_PC_53, _MCW_PC); |
| 84 | #endif | 75 | #endif |
| 85 | return _tmain(__argc, __targv, _tenviron); | 76 | return _tmain(__argc, __targv, _tenviron); |
| @@ -23,71 +23,53 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); · 22 unmodified lines | |||
| 23 | #define _runtwinmain _runwinmain | 23 | #define _runtwinmain _runwinmain |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | typedef struct | 26 | typedef struct { int newmode; } _startupinfo; |
| 27 | { | ||
| 28 | int newmode; | ||
| 29 | } _startupinfo; // CLI Vs GUI | ||
| 30 | |||
| 31 | int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); | 27 | int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); |
| 32 | 28 | ||
| 33 | int _twinstart(void) | 29 | static int go_winmain(TCHAR *arg1) |
| 34 | { | 30 | { |
| 35 | __TRY__ | 31 | STARTUPINFO si; |
| 36 | _TCHAR *szCmd, *p; | 32 | _TCHAR *szCmd, *p; |
| 37 | STARTUPINFO startinfo; | ||
| 38 | _startupinfo start_info_con = {0}; | ||
| 39 | int fShow; | 33 | int fShow; |
| 40 | int ret; | ||
| 41 | |||
| 42 | __set_app_type(__GUI_APP); | ||
| 43 | _controlfp(0x10000, 0x30000); | ||
| 44 | 34 | ||
| 45 | start_info_con.newmode = 0; | 35 | GetStartupInfo(&si); |
| 46 | __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con); | 36 | if (si.dwFlags & STARTF_USESHOWWINDOW) |
| 37 | fShow = si.wShowWindow; | ||
| 38 | else | ||
| 39 | fShow = SW_SHOWDEFAULT; | ||
| 47 | 40 | ||
| 48 | p = GetCommandLine(); | 41 | szCmd = NULL, p = GetCommandLine(); |
| 49 | if (__argc > 1) | 42 | if (arg1) |
| 50 | szCmd = _tcsstr(p, __targv[1]); | 43 | szCmd = _tcsstr(p, arg1); |
| 51 | if (NULL == szCmd) | 44 | if (NULL == szCmd) |
| 52 | szCmd = __T(""); | 45 | szCmd = _tcsdup(__T("")); |
| 53 | else if (szCmd > p && szCmd[-1] == __T('\"')) | 46 | else if (szCmd > p && szCmd[-1] == __T('"')) |
| 54 | --szCmd; | 47 | --szCmd; |
| 48 | #if defined __i386__ || defined __x86_64__ | ||
| 49 | _controlfp(0x10000, 0x30000); | ||
| 50 | #endif | ||
| 51 | return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); | ||
| 52 | } | ||
| 55 | 53 | ||
| 56 | GetStartupInfo(&startinfo); | 54 | int _twinstart(void) |
| 57 | fShow = startinfo.wShowWindow; | 55 | { |
| 58 | if (0 == (startinfo.dwFlags & STARTF_USESHOWWINDOW)) | 56 | __TRY__ |
| 59 | fShow = SW_SHOWDEFAULT; | 57 | _startupinfo start_info_con = {0}; |
| 60 | 58 | __set_app_type(__GUI_APP); | |
| 61 | ret = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); | 59 | __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con); |
| 62 | exit(ret); | 60 | exit(go_winmain(__argc > 1 ? __targv[1] : NULL)); |
| 63 | } | 61 | } |
| 64 | 62 | ||
| 65 | int _runtwinmain(int argc, /* as tcc passed in */ char **argv) | 63 | int _runtwinmain(int argc, /* as tcc passed in */ char **argv) |
| 66 | { | 64 | { |
| 67 | _TCHAR *szCmd, *p; | ||
| 68 | |||
| 69 | #ifdef UNICODE | 65 | #ifdef UNICODE |
| 70 | _startupinfo start_info = {0}; | 66 | _startupinfo start_info = {0}; |
| 71 | |||
| 72 | __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info); | 67 | __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info); |
| 73 | /* may be wrong when tcc has received wildcards (*.c) */ | 68 | /* may be wrong when tcc has received wildcards (*.c) */ |
| 74 | if (argc < __argc) { | 69 | if (argc < __argc) |
| 75 | __targv += __argc - argc; | 70 | __targv += __argc - argc, __argc = argc; |
| 76 | __argc = argc; | ||
| 77 | } | ||
| 78 | #else | 71 | #else |
| 79 | __argc = argc; | 72 | __argc = argc, __targv = argv; |
| 80 | __targv = argv; | ||
| 81 | #endif | 73 | #endif |
| 82 | 74 | return go_winmain(__argc > 1 ? __targv[1] : NULL); | |
| 83 | p = GetCommandLine(); | ||
| 84 | szCmd = NULL; | ||
| 85 | if (argc > 1) | ||
| 86 | szCmd = _tcsstr(p, __targv[1]); | ||
| 87 | if (NULL == szCmd) | ||
| 88 | szCmd = __T(""); | ||
| 89 | else if (szCmd > p && szCmd[-1] == __T('\"')) | ||
| 90 | --szCmd; | ||
| 91 | _controlfp(0x10000, 0x30000); | ||
| 92 | return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT); | ||
| 93 | } | 75 | } |
| @@ -108,6 +108,8 @@ · 107 unmodified lines | |||
| 108 | ------------------------ | 108 | ------------------------ |
| 109 | * You can use the MinGW and MSYS tools available at | 109 | * You can use the MinGW and MSYS tools available at |
| 110 | http://www.mingw.org | 110 | http://www.mingw.org |
| 111 | http://www.mingw-w64.org | ||
| 112 | http://www.msys2.org | ||
| 111 | 113 | ||
| 112 | Untar the TCC archive and type in the MSYS shell: | 114 | Untar the TCC archive and type in the MSYS shell: |
| 113 | ./configure [--prefix installpath] | 115 | ./configure [--prefix installpath] |
| @@ -116,29 +118,22 @@ · 2 unmodified lines | |||
| 116 | 118 | ||
| 117 | The default install location is c:\Program Files\tcc | 119 | The default install location is c:\Program Files\tcc |
| 118 | 120 | ||
| 121 | Cygwin can be used too with its mingw cross-compiler installed: | ||
| 122 | ./configure --cross-prefix=i686-w64-mingw32- | ||
| 123 | (the prefix may vary) | ||
| 124 | |||
| 119 | * Alternatively you can compile TCC with just GCC from MinGW using | 125 | * Alternatively you can compile TCC with just GCC from MinGW using |
| 120 | > build-tcc.bat (from the win32 directory) | 126 | > build-tcc.bat (from the win32 directory) |
| 121 | 127 | ||
| 122 | Also MSVC can be used with the "VSTools Developer Command Prompt": | 128 | Also MSVC can be used with the "VSTools Developer Command Prompt": |
| 123 | > build-tcc.bat -c cl | 129 | > build-tcc.bat -c cl |
| 124 | 130 | ||
| 125 | or with a tcc (needs to be in a different directory) | 131 | or with an existing tcc (needs to be in a different directory) |
| 126 | > build-tcc.bat -c some-tcc-dir\tcc.exe | 132 | > build-tcc.bat -c some-tcc-dir\tcc.exe |
| 127 | 133 | ||
| 128 | Also you can copy/install everything into another directory: | 134 | Also you can copy/install everything into another directory: |
| 129 | > build-tcc.bat -i <dir> | 135 | > build-tcc.bat -i <dir> |
| 130 | 136 | ||
| 131 | * You can also bootstrap a native tcc Windows toolchain with cygwin. | ||
| 132 | https://www.cygwin.com/ | ||
| 133 | |||
| 134 | Install Base, gcc, make | ||
| 135 | Launch Cygwin Terminal | ||
| 136 | > make | ||
| 137 | or to force 32bit executables (including 64bit backend) | ||
| 138 | > make TARGET=32 | ||
| 139 | or to force 64bit executables (including 32bit backend) | ||
| 140 | > make TARGET=64 | ||
| 141 | |||
| 142 | Limitations: | 137 | Limitations: |
| 143 | ------------ | 138 | ------------ |
| 144 | - On the object file level, currently TCC supports only the ELF format, | 139 | - On the object file level, currently TCC supports only the ELF format, |