diff --git a/Makefile b/Makefile index d5456a3..3e9a008 100644 --- a/Makefile +++ b/Makefile @@ -9,11 +9,15 @@ CFLAGS_P=$(CFLAGS) -pg -static -DCONFIG_TCC_STATIC LIBS_P= CFLAGS+=-m386 -malign-functions=0 +CFLAGS+=-DCONFIG_TCC_PREFIX=\"$(prefix)\" DISAS=objdump -d INSTALL=install -VERSION=0.9.7 +VERSION=0.9.8 -all: tcc +# run local version of tcc with local libraries and includes +TCC=./tcc -B. -I. + +all: tcc libtcc1.o bcheck.o tcc-doc.html # auto test @@ -27,19 +31,19 @@ test.ref: tcctest.ref ./tcctest.ref > $@ test.out: tcc tcctest.c - ./tcc -I. tcctest.c > $@ + $(TCC) tcctest.c > $@ run: tcc tcctest.c - ./tcc -I. tcctest.c + $(TCC) tcctest.c # iterated test2 (compile tcc then compile tcctest.c !) test2: tcc tcc.c tcctest.c test.ref - ./tcc -I. tcc.c -I. tcctest.c > test.out2 + $(TCC) tcc.c -B. -I. tcctest.c > test.out2 @if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi # iterated test3 (compile tcc then compile tcc then compile tcctest.c !) test3: tcc tcc.c tcctest.c test.ref - ./tcc -I. tcc.c -I. tcc.c -I. tcctest.c > test.out3 + $(TCC) tcc.c -B. -I. tcc.c -B. -I. tcctest.c > test.out3 @if diff -u test.ref test.out3 ; then echo "Auto Test3 OK"; fi # memory and bound check auto test @@ -48,14 +52,14 @@ BOUNDS_FAIL= 2 5 7 9 11 12 13 btest: boundtest.c tcc @for i in $(BOUNDS_OK); do \ - if ./tcc -b boundtest.c $$i ; then \ + if $(TCC) -b boundtest.c $$i ; then \ /bin/true ; \ else\ echo Failed positive test $$i ; exit 1 ; \ fi ;\ done ;\ for i in $(BOUNDS_FAIL); do \ - if ./tcc -b boundtest.c $$i ; then \ + if $(TCC) -b boundtest.c $$i ; then \ echo Failed negative test $$i ; exit 1 ;\ else\ /bin/true ; \ @@ -78,17 +82,27 @@ ex3: ex3.c # Native Tiny C Compiler -tcc_g: tcc.c i386-gen.c bcheck.c Makefile +tcc_g: tcc.c i386-gen.c bcheck.c tcctok.h libtcc.h Makefile gcc $(CFLAGS) -o $@ $< $(LIBS) tcc: tcc_g strip -s -R .comment -R .note -o $@ $< -install: tcc +# TinyCC runtime libraries +libtcc1.o: libtcc1.c + gcc -O2 -Wall -c -o $@ $< + +bcheck.o: bcheck.c + gcc -O2 -Wall -c -o $@ $< + +install: tcc libtcc1.o bcheck.o $(INSTALL) -m755 tcc $(prefix)/bin + $(INSTALL) tcc.1 $(prefix)/man/man1 mkdir -p $(prefix)/lib/tcc + mkdir -p $(prefix)/lib/tcc/include + $(INSTALL) -m644 libtcc1.o bcheck.o $(prefix)/lib/tcc $(INSTALL) -m644 stdarg.h stddef.h float.h stdbool.h \ - tcclib.h $(prefix)/lib/tcc + tcclib.h $(prefix)/lib/tcc/include clean: rm -f *~ *.o tcc tcc1 tcct tcc_g tcctest.ref *.bin *.i ex2 \ @@ -131,7 +145,7 @@ libtcc_test: libtcc_test.c libtcc.a # targets for development %.bin: %.c tcc - ./tcc -g -o $@ -I. $< + $(TCC) -g -o $@ $< $(DISAS) $@ instr: instr.o @@ -140,6 +154,10 @@ instr: instr.o instr.o: instr.S gcc -O2 -Wall -g -c -o $@ $< +# documentation +tcc-doc.html: tcc-doc.texi + texi2html -monolithic -number $< + FILE=tcc-$(VERSION) tar: @@ -148,8 +166,10 @@ tar: ( cd /tmp ; tar zcvf ~/$(FILE).tar.gz \ $(FILE)/Makefile $(FILE)/Makefile.uClibc \ $(FILE)/README $(FILE)/TODO $(FILE)/COPYING \ - $(FILE)/Changelog $(FILE)/tcc-doc.html \ - $(FILE)/tcc.c $(FILE)/i386-gen.c $(FILE)/bcheck.c \ + $(FILE)/Changelog $(FILE)/tcc-doc.texi $(FILE)/tcc-doc.html \ + $(FILE)/tcc.1 \ + $(FILE)/tcc.c $(FILE)/i386-gen.c $(FILE)/tcctok.h \ + $(FILE)/bcheck.c $(FILE)/libtcc1.c \ $(FILE)/il-opcodes.h $(FILE)/il-gen.c \ $(FILE)/elf.h $(FILE)/stab.h $(FILE)/stab.def \ $(FILE)/stddef.h $(FILE)/stdarg.h $(FILE)/stdbool.h $(FILE)/float.h \ diff --git a/README b/README index 4cc3924..86b4bd4 100644 --- a/README +++ b/README @@ -75,38 +75,6 @@ when doing 'make test'. Please read tcc-doc.html to have all the features of TCC. -Technical Description: ---------------------- - -This is not my first C compiler (see my 'fbcc' compiler) but it -contains the first C preprocessor I wrote. The project started as a -joke to make the smallest C compiler. Then I expanded it torward -ISOC99 compliance. This C compiler is particular because each feature -was added while trying to be as simple and compact as possible. For -example, no intermediate structure is used to store code or -expressions. - -The TCC code generator directly generates linked binary code. It is -rather unusual these days (see gcc for example which generates text -assembly), but it allows to be very fast and surprisingly not so -complicated. - -The TCC code generator is register based. It means that it could even -generate not so bad code for RISC processors. On x86, three temporary -registers are used. When more registers are needed, one register is -flushed in a new local variable. - -Constant propagation is done for all operations. Multiplications and -divisions are optimized to shifts when appropriate. Comparison -operators are optimized by maintaining a special cache for the -processor flags. &&, || and ! are optimized by maintaining a special -'jump target' value. No other jump optimization is currently performed -because it would require to store the code in a more abstract fashion. - -The types are stored in a single 'int' variable (see VT_xxx -constants). It was choosen in the first stages of development when tcc -was much simpler. Now, it may not be the best solution. - License: ------- diff --git a/TODO b/TODO index 5a11505..d0cc5d3 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,14 @@ TODO list: -Critical: -- better local symbol handling (needed for other targets) +- relocate .stabs information +- fix -I search order (same as gcc) +- dynamic hash table resizing +- better section generator (suppress mmaps) +- relocate .bounds section content +- add size info on all ELF symbols +- add separate symbol/offset handling +- better local variables handling (needed for other targets) - handle void (__attribute__() *ptr)() -- optimize slightly bound checking when doing addition + dereference. -- better section generator (suppress some mmaps). - To check: bound checking and float/long long/struct copy code - To fix: 'sizeof' generate code if too complex expression is given. - fix bound check code with '&' on local variables (currently done @@ -21,11 +25,9 @@ Not critical: - fix multiple compound literals inits in blocks (ISOC99 normative example - only relevant when using gotos! -> must add boolean variable to tell if compound literal was already initialized). -- add more bounds checked functions (strcpy, ...) - fix L"\x1234" wide string case (need to store them as utf8 ?) - fix preprocessor symbol redefinition - better constant opt (&&, ||, ?:) -- add ELF executable and shared library output option (would be needed - for completness!). - add portable byte code generator and interpreter for other unsupported architectures. +- C++: variable declaration in for, minimal 'class' support. diff --git a/tcc-doc.texi b/tcc-doc.texi index 3a9a10e..8fccadb 100644 --- a/tcc-doc.texi +++ b/tcc-doc.texi @@ -36,8 +36,8 @@ generation (@xref{libtcc}). @section Quick start @example -usage: tcc [-c] [-o outfile] [-bench] [-Idir] [-Dsym[=val]] [-Usym] - [-g] [-b] [-llib] [-shared] [-static] +usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym] + [-g] [-b] [-Ldir] [-llib] [-shared] [-static] [--] infile1 [infile2... --] [infile_args...] @end example @@ -99,8 +99,12 @@ Generate an object file (@samp{-o} option must also be given). @item -o outfile Put object file, executable, or dll into output file @file{outfile}. +@item -Bdir +Set the path where the tcc internal libraries can be found (default is +@code{prefix}@file{/lib/tcc}. + @item -bench -Output compilation statistics +Output compilation statistics. @end table Preprocessor options: @@ -108,8 +112,9 @@ Preprocessor options: @table @samp @item -Idir Specify an additionnal include path. The default ones are: -@file{/usr/include}, @code{prefix}@file{/lib/tcc/include} (@code{prefix} -is usually @file{/usr} or @file{/usr/local}). +@file{/usr/local/include}, @code{prefix}@file{/lib/tcc/include} and +@file{/usr/include} (@code{prefix} is usually @file{/usr} or +@file{/usr/local}). @item -Dsym[=val] Define preprocessor symbol 'sym' to @@ -138,13 +143,18 @@ that the generated code is slower and bigger in this case. Linker options: @table @samp +@item -Ldir +Specify an additionnal static library path for the @samp{-l} option. The +default library paths are @file{/usr/local/lib}, @file{/usr/lib} and @file{/lib}. + @item -lxxx -Dynamically link your program with library -libxxx.so. Standard library paths are checked, including those -specified with LD_LIBRARY_PATH. +Link your program with dynamic library libxxx.so or static library +libxxx.a. The library is searched in the paths specified by the +@samp{-L} option. @item -shared -Generate a shared library instead of an executable (@samp{-o} option must also be given). +Generate a shared library instead of an executable (@samp{-o} option +must also be given). @item -static Generate a statically linked executable (default is a shared linked @@ -314,6 +324,47 @@ indicate that you use TCC. @end itemize +@chapter TinyCC Linker + +@section ELF file generation + +TCC can directly output relocatable ELF files (object files), +executable ELF files and dynamic ELF libraries without relying on an +external linker. + +Dynamic ELF libraries are not working correctly yet because the C +compiler does not generate position independant code (PIC) code. + +TCC linker cannot currently suppress unused object code. But TCC +will soon integrate a novel feature not found in GNU tools: unused code +will be suppressed at the function or variable level, provided you only +use TCC to compile your files. + +ELF symbol hash table is currently fixed. + +@section ELF file loader + +TCC can load ELF object files, archives (.a files) and dynamic +libraries (.so). + +Currently, the @code{stabs} debug information is not relocated. + +@section GNU Linker Scripts + +Because on many Linux systems some dynamic libraries (such as +@file{/usr/lib/libc.so}) are in fact GNU ld link scripts (horrible!), +TCC linker also support a subset of GNU ld scripts. + +The @code{GROUP} and @code{FILE} commands are supported. + +Example from @file{/usr/lib/libc.so}: +@example +/* GNU ld script + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ +GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a ) +@end example + @node bounds @chapter TinyCC Memory and Bound checks