aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* configure: use relative paths for in-tree buildgrischka2013-01-303-16/+19
| | | | | | Also - move CPPFLAGS to Makefile - Use top_srcdir in lib/Makefile
* Add my copyright for changes in arm-gen.cThomas Preud'homme2013-01-301-0/+1
|
* Changelog updateThomas Preud'homme2013-01-301-0/+1
|
* Update ChangelogThomas Preud'homme2013-01-301-0/+2
|
* Favor arm hardfloat over arm softfloat.Thomas Preud'homme2013-01-291-4/+4
| | | | | | | Favor ARM hardfloat over ARM softfloat calling convention. In particular, this solve the problem of the raspbian distribution where the softfloat ld.so pathname (lib/ld-linux.so.3) is actually a symlink to the hardfloat ld.so pathname (/lib/arm-linux-gnueabihf/ld-2.13.so).
* Fix overflow detection in ARM relocationThomas Preud'homme2013-01-281-2/+2
| | | | | | Fix overflow detection for R_ARM_CALL, R_ARM_PC24, R_ARM_JUMP24 and R_ARM_PLT32 relocations on ARM. 26 bits means 25 bits for positive and negative offsets !
* Fix stack alignment on 8 bytes at function callThomas Preud'homme2013-01-271-3/+3
| | | | | Ensure stack pointer is correctly adjusted in prolog to be aligned on 8 bytes after the change of frame linking.
* Don't do builtin_frame_address test with ARM gccThomas Preud'homme2013-01-261-0/+2
| | | | | | | | gcc fails the builtin_frame_address test on ARM so we disable it. As a consequence, the diff between gcc and tcc's output is unecessarily bigger. Given the big size of the diff currently, this doesn't make a big difference but may allow to detect a regression in tcc's implementation of builtin_frame_address.
* Organize frames in a real linked list on ARMThomas Preud'homme2013-01-261-5/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Change the linking of the frames on ARM. Instead of having fp points 12 bytes above where the old fp is stored, let fp points where the old fp is stored. That is, we switch from: | . | | . | | . | | | | params | <-- fp -------- | oldlr | -------- | oldip | -------- | oldfp | -------- to: | . | | . | | . | | | | params | -------- | oldlr | -------- | oldip | -------- | oldfp | <-- fp --------
* Use gcc to generate tcctest.gccThomas Preud'homme2013-01-251-1/+1
|
* Link STT_GNU_IFUNC into STT_FUNC in executable.Thomas Preud'homme2013-01-251-2/+11
| | | | | | | | Indirect functions shall have STT_FUNC type in executable dynsym section. Indeed, a dlsym call following a lazy resolution would pick the symbol value from the executable dynsym entry. This would contain the address of the function wanted by the caller of dlsym instead of the address of the function that would return that address.
* win32: _mingw.h: do not undef NULLgrischka2013-01-242-2/+1
| | | | | | | | | Not wise if stddef.h was already included. This is related to commit 3aa26a794e24a298493a2bc9d70fbd9aebf6437a Instead hack stddef.h to have identical definition and thus avoid the issue mentionned there.
* Fix [f]getc return value usage in 40_stdio testThomas Preud'homme2013-01-241-1/+1
| | | | | | Store [f]getc return value into an int instead of char, as per prototype. This fix an issue when char is unsigned (as is on arm for both tcc and gcc).
* Revert "Optimize vswap()"grischka2013-01-142-33/+8
| | | | | | | | | | This reverts commit 63193d1794b037eb4f3b6551596fa8a6d423e0c3. Had some problems (_STATIC_ASSERT) and was too ugly anyway. For retry, I'd suggest to implement a general function static inline void memswap (void *p1, void* p2, size_t n); and then use that. If you do so, please keep the original code as comment.
* Revert mistake in "win32: malloc.h: fix win32 ... _STATIC_ASSERT"grischka2013-01-142-69/+0
| | | | | | | from commit fc574f14984d11f1ead50560d1bdc5ae0eaf6d8d. The files from include are copied to win32/include with make install or build-tcc.bat.
* Fix out-of-tree build with relative path to rootThomas Preud'homme2013-01-141-2/+2
| | | | | Fix path of Makefile symlinks in a out-of-tree build where the root directory of the source is given as a relative path.
* Install libtcc.h when invoking make installThomas Preud'homme2013-01-141-0/+2
| | | | This fix commit e79281f58ec302e8cc9dfc7d00e06f426fcd2acd
* Revert "Added what I call virtual io to tinycc this way we can make a ↵Thomas Preud'homme2013-01-1412-903/+62
| | | | | | | | monolitic executable or library that contains all needed to compile programs, truly tinycc portable." This reverts commit 59e18aee0e509a3ca75dbe6f909e18c1d17893d1. tcc is being stabilized now in order to do a new release soon. Therefore, such a change is not appropriate now.
* Revert "pe: fix tcc not linking to user32 and gdi32"Thomas Preud'homme2013-01-141-1/+1
| | | | | | This reverts commit 943574aba54713ca4a17fe33aadde5abee233b53. The empty string in "libs" was intended behavior, as can be seen from the "if (0 == *p)" below.
* Stop setting -Wno-unused-result switch in MakefileThomas Preud'homme2013-01-131-11/+0
| | | | | | | | | | This commit revert commit 061b5799cc1feb15014da589ea98057deda14a23 and subsequent commits to detect whether -Wno-unused-result is supported or not by the compiler used to compile tcc. No warning about unused results is issued in a normal build and thus this switch is only needed if calling make with extra switches in CFLAGS or CPPFLAGS. It should thus be added with the extra switches when calling make and not in the Makefile.
* Fix C99ism in vswap()Thomas Preud'homme2013-01-131-1/+2
| | | | | Declare vtopl in vswap at the beginning of the function before any assignments. Doing otherwise means C99 is assumed when compiling.
* Added what I call virtual io to tinycc this way we can make a monolitic ↵mingodad2013-01-1112-62/+903
| | | | | | executable or library that contains all needed to compile programs, truly tinycc portable. Tested under linux exec the "mk-it" shell script and you'll end up with a portable tinycc executable that doesn't depend on anything else.
* Fix "Optimize cstr_reset() to only reset string to empty"grischka2013-01-061-1/+1
| | | | | | This fixes commit 8eb92e605200b1fe8d570ad309e28245c3f1af0a Remove memory leak.
* tccpp: alternative fix for #include_next infinite loop buggrischka2013-01-064-78/+39
| | | | | | | | | | | | | | | This replaces commit 3d409b08893873b917ccb8c34398bc41a4e84d7c - revert old fix in libtcc.c - #include_next: look up the file in the include stack to see if it is already included. Also: - streamline include code - remove 'type' from struct CachedInclude (obsolete because we check full filename anyway) - remove inc_type & inc_filename from struct Bufferedfile (obsolete) - fix bug with TOK_FLAG_ENDIF not being reset - unrelated: get rid of an 'variable potentially uninitialized' warning
* Stop returning 0 in cmp_comparison_testThomas Preud'homme2013-01-061-1/+0
| | | | cmp_comparison_test has no return value and should thus not return 0.
* Honor CC when testing for -Wno-unused-resultThomas Preud'homme2013-01-061-1/+1
| | | | | | The compiler used for compiling tcc is the one referenced in the CC variable. As such, the check for -Wno-unused-result presence should be done on CC.
* win32: malloc.h: fix win32 tcc-tcc complication by correcting ↵Roy2012-12-313-1/+70
| | | | | | _STATIC_ASSERT, ideas from mingw-w64 changeset 4293 stdarg.h, stddef.h: _mingw.h needs them
* Optimize vswap()Kirill Smelkov2012-12-212-5/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | vswap() is called often enough and shows in profile and it was easy to hand optimize swapping vtop[-1] and vtop[0] - instead of large (28 bytes on i386) tmp variable and two memory to memory copies, let's swap areas by longs through registers with streamlined assembly. For $ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c before: # Overhead Command Shared Object Symbol # ........ ........... ................... .............................................. # 15.19% tcc tcc [.] next_nomacro1 5.19% tcc libc-2.13.so [.] _int_malloc 4.57% tcc tcc [.] next 3.36% tcc tcc [.] tok_str_add2 3.03% tcc tcc [.] macro_subst_tok 2.93% tcc tcc [.] macro_subst 2.53% tcc tcc [.] next_nomacro_spc 2.49% tcc tcc [.] vswap 2.36% tcc libc-2.13.so [.] _int_free │ ST_FUNC void vswap(void) │ { 1,96 │ push %edi 2,65 │ push %esi 1,08 │ sub $0x20,%esp │ SValue tmp; │ │ /* cannot let cpu flags if other instruction are generated. Also │ avoid leaving VT_JMP anywhere except on the top of the stack │ because it would complicate the code generator. */ │ if (vtop >= vstack) { 0,98 │ mov 0x8078cac,%eax │ cmp $0x8078d3c,%eax 1,18 │ ┌──jb 24 │ │ int v = vtop->r & VT_VALMASK; 1,08 │ │ mov 0x8(%eax),%edx 0,78 │ │ and $0x3f,%edx │ │ if (v == VT_CMP || (v & ~1) == VT_JMP) 0,78 │ │ cmp $0x33,%edx 0,69 │ │↓ je 54 0,59 │ │ and $0xfffffffe,%edx 0,49 │ │ cmp $0x34,%edx 0,29 │ │↓ je 54 │ │ gv(RC_INT); │ │ } │ │ tmp = vtop[0]; 1,08 │24:└─→lea 0x4(%esp),%edi 0,39 │ mov $0x7,%ecx │ mov %eax,%esi 14,41 │ rep movsl %ds:(%esi),%es:(%edi) │ vtop[0] = vtop[-1]; 9,51 │ lea -0x1c(%eax),%esi 1,96 │ mov $0x7,%cl │ mov %eax,%edi 17,06 │ rep movsl %ds:(%esi),%es:(%edi) │ vtop[-1] = tmp; 10,20 │ mov 0x8078cac,%edi 2,35 │ sub $0x1c,%edi 0,78 │ lea 0x4(%esp),%esi │ mov $0x7,%cl 15,20 │ rep movsl %ds:(%esi),%es:(%edi) │ } 9,90 │ add $0x20,%esp 2,25 │ pop %esi 1,67 │ pop %edi 0,69 │ ret after: # Overhead Command Shared Object Symbol # ........ ........... ................... .............................................. # 15.27% tcc tcc [.] next_nomacro1 5.08% tcc libc-2.13.so [.] _int_malloc 4.57% tcc tcc [.] next 3.17% tcc tcc [.] tok_str_add2 3.12% tcc tcc [.] macro_subst 2.99% tcc tcc [.] macro_subst_tok 2.43% tcc tcc [.] next_nomacro_spc 2.32% tcc libc-2.13.so [.] _int_free . . . 0.71% tcc tcc [.] vswap │ ST_FUNC void vswap(void) │ { 7,22 │ push %eax │ /* cannot let cpu flags if other instruction are generated. Also │ avoid leaving VT_JMP anywhere except on the top of the stack │ because it would complicate the code generator. */ │ if (vtop >= vstack) { 11,34 │ mov 0x8078cac,%eax 2,75 │ cmp $0x8078d3c,%eax 0,34 │ ┌──jb 20 │ │ int v = vtop->r & VT_VALMASK; 0,34 │ │ mov 0x8(%eax),%edx 8,93 │ │ and $0x3f,%edx │ │ if (v == VT_CMP || (v & ~1) == VT_JMP) 2,06 │ │ cmp $0x33,%edx 2,41 │ │↓ je 74 2,41 │ │ and $0xfffffffe,%edx 0,34 │ │ cmp $0x34,%edx 2,41 │ │↓ je 74 │ │ vtopl[-1*VSIZEL + i] = tmpl; \ │ │ } do {} while (0) │ │ │ │ VSWAPL(15); VSWAPL(14); VSWAPL(13); VSWAPL(12); │ │ VSWAPL(11); VSWAPL(10); VSWAPL( 9); VSWAPL( 8); │ │ VSWAPL( 7); VSWAPL( 6); VSWAPL( 5); VSWAPL( 4); 2,06 │20:└─→mov 0x18(%eax),%edx 1,37 │ mov -0x4(%eax),%ecx 2,06 │ mov %ecx,0x18(%eax) 1,37 │ mov %edx,-0x4(%eax) 2,06 │ mov 0x14(%eax),%edx 2,06 │ mov -0x8(%eax),%ecx 2,41 │ mov %ecx,0x14(%eax) 3,09 │ mov %edx,-0x8(%eax) 3,09 │ mov 0x10(%eax),%edx 1,72 │ mov -0xc(%eax),%ecx 2,75 │ mov %ecx,0x10(%eax) 1,72 │ mov %edx,-0xc(%eax) │ VSWAPL( 3); VSWAPL( 2); VSWAPL( 1); VSWAPL( 0); 2,41 │ mov 0xc(%eax),%edx 2,41 │ mov -0x10(%eax),%ecx 2,41 │ mov %ecx,0xc(%eax) 0,69 │ mov %edx,-0x10(%eax) 1,72 │ mov 0x8(%eax),%edx 0,69 │ mov -0x14(%eax),%ecx 1,03 │ mov %ecx,0x8(%eax) 1,37 │ mov %edx,-0x14(%eax) 1,37 │ mov 0x4(%eax),%edx 0,69 │ mov -0x18(%eax),%ecx 3,09 │ mov %ecx,0x4(%eax) 2,06 │ mov %edx,-0x18(%eax) 1,37 │ mov (%eax),%edx 2,41 │ mov -0x1c(%eax),%ecx 1,37 │ mov %ecx,(%eax) 4,12 │ mov %edx,-0x1c(%eax) │ } │ │ # undef VSWAPL │ # undef VSIZEL │ } 1,03 │ pop %eax 3,44 │ ret Overal speedup: # best of 5 runs before: 8268 idents, 47203 lines, 1526763 bytes, 0.148 s, 319217 lines/s, 10.3 MB/s after: 8273 idents, 47231 lines, 1527685 bytes, 0.146 s, 324092 lines/s, 10.5 MB/s Static ASSERT macro taken from CCAN's[1] build_assert[2] which is in public domain. [1] http://ccodearchive.net/ [2] http://git.ozlabs.org/?p=ccan;a=blob;f=ccan/build_assert/build_assert.h;h=24e59c44cd930173178ac9b6e101b0af64a879e9;hb=HEAD
* Optimize cstr_reset() to only reset string to empty, not call free() and ↵Kirill Smelkov2012-12-212-1/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | later malloc() A CString could be reset to empty just setting its .size to 0. If memory was already allocated, that would be remembered in .data_allocated and .size_allocated and on consequent string manipulations that memory will be used without immediate need to call malloc(). For $ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c after the patch malloc/free are called less often: (tcc is run in loop; perf record -a sleep 10 && perf report) before: # Overhead Command Shared Object Symbol # ........ ........... .................. .......................................... # 13.89% tcc tcc [.] next_nomacro1 4.73% tcc libc-2.13.so [.] _int_malloc 4.39% tcc tcc [.] next 2.94% tcc tcc [.] tok_str_add2 2.78% tcc tcc [.] macro_subst_tok 2.75% tcc libc-2.13.so [.] free 2.74% tcc tcc [.] macro_subst 2.63% tcc libc-2.13.so [.] _int_free 2.28% tcc tcc [.] vswap 2.24% tcc tcc [.] next_nomacro_spc 2.06% tcc libc-2.13.so [.] realloc 2.00% tcc libc-2.13.so [.] malloc 1.99% tcc tcc [.] unary 1.85% tcc libc-2.13.so [.] __i686.get_pc_thunk.bx 1.76% kworker/0:1 [kernel.kallsyms] [k] delay_tsc 1.70% tcc tcc [.] next_nomacro 1.62% tcc tcc [.] preprocess 1.41% tcc libc-2.13.so [.] __memcmp_ssse3 1.38% tcc [kernel.kallsyms] [k] memset 1.10% tcc tcc [.] g 1.06% tcc tcc [.] parse_btype 1.05% tcc tcc [.] sym_push2 1.04% tcc libc-2.13.so [.] _int_realloc 1.00% tcc libc-2.13.so [.] malloc_consolidate after: # Overhead Command Shared Object Symbol # ........ ........... .................. .............................................. # 15.26% tcc tcc [.] next_nomacro1 5.07% tcc libc-2.13.so [.] _int_malloc 4.62% tcc tcc [.] next 3.22% tcc tcc [.] tok_str_add2 3.03% tcc tcc [.] macro_subst_tok 3.02% tcc tcc [.] macro_subst 2.59% tcc tcc [.] next_nomacro_spc 2.44% tcc tcc [.] vswap 2.39% tcc libc-2.13.so [.] _int_free 2.28% tcc libc-2.13.so [.] free 2.22% tcc tcc [.] unary 2.07% tcc libc-2.13.so [.] realloc 1.97% tcc libc-2.13.so [.] malloc 1.70% tcc tcc [.] preprocess 1.69% tcc libc-2.13.so [.] __i686.get_pc_thunk.bx 1.68% tcc tcc [.] next_nomacro 1.59% tcc [kernel.kallsyms] [k] memset 1.55% tcc libc-2.13.so [.] __memcmp_ssse3 1.22% tcc tcc [.] parse_comment 1.11% tcc tcc [.] g 1.11% tcc tcc [.] sym_push2 1.10% tcc tcc [.] parse_btype 1.10% tcc libc-2.13.so [.] _int_realloc 1.06% tcc tcc [.] vsetc 0.98% tcc libc-2.13.so [.] malloc_consolidate and this gains small speedup for tcc: # best of 5 runs before: 8268 idents, 47191 lines, 1526670 bytes, 0.153 s, 307997 lines/s, 10.0 MB/s after: 8268 idents, 47203 lines, 1526763 bytes, 0.148 s, 319217 lines/s, 10.3 MB/s
* build: fix out-of-tree installAkim Demaille2012-12-211-3/+1
| | | | | Makefile (install): Fix installation of headers. Do not try to install twice libtcc.h, once should be enough.
* build: fix out-of-tree buildAkim Demaille2012-12-211-1/+1
| | | | * Makefile (TCC-VERSION): Use top_srcdir.
* build: simplify the makefilesAkim Demaille2012-12-211-18/+6
| | | | * Makefile: use "else if" to improve readability.
* configure: support absolete out-of-tree buildsAkim Demaille2012-12-212-5/+10
| | | | | configure: handle the case of absolute paths. Reported by grishka.
* configure: style changesAkim Demaille2012-12-211-11/+13
| | | | * configure: use more here-documents.
* configure: prefer here-documentsAkim Demaille2012-12-211-53/+53
| | | | | * configure: use here-documents to improve readability and reduce the clutter.
* configure: style changesAkim Demaille2012-12-211-13/+7
| | | | | * configure (case $targetos): Improve readibility. (case $cpu): New, to improve readability compare to if + test.
* Makefile: revamp "tar" targetgrischka2012-12-201-10/+17
| | | | | | | | - Creates release tarball from *current* git branch - Includes tcc-doc.html - converts important windows files files to CRLF (requirement for the cmd.exe batch processor, convenience for reading the txt in notepad)
* win32: build-tcc.bat: get rid of hardcoded VERSION stringgrischka2012-12-202-11/+7
| | | | | | | Also: - put libtcc.def into libtcc dir - remove ar references - remove libtcc_test from build
* build: fix VPATH buildsAkim Demaille2012-12-186-25/+55
| | | | | | | | | | * configure (fn_dirname): New. Use it to ensure the creation of proper symlinks to Makefiles. (config.mak): Define top_builddir and top_srcdir. (CPPFLAGS): Be sure to find the headers. * Makefile, lib/Makefile, tests/Makefile, tests2/Makefile: Adjust to set VPATH properly. Fix confusion between top_builddir and top_srcdir.
* bcheck: there is no unistd.h in win32.Roy2012-12-101-0/+2
|
* Repair bounds-checking more, this time `tcc -b -run tcc.c -run tcc.c -run ↵Kirill Smelkov2012-12-096-11/+56
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | tcctest.c` works Hello up there. On the list Grischka made a point that we can't recommend using -b as long as tcc -b tcc.c doesn't produce anything useful. Now it does, so please don't treat -b mode as second class citizen anymore. Thanks, Kirill * bcheck2: tests: Add tests for compile/run tcc.c with `tcc -b` then compile tcc.c again, then run tcctest.c lib/bcheck: Fix code typo in __bound_delete_region() lib/bcheck: Don't assume heap goes right after bss Make tcc work after self-compiling with bounds-check enabled
| * tests: Add tests for compile/run tcc.c with `tcc -b` then compile tcc.c ↵Kirill Smelkov2012-12-092-1/+25
| | | | | | | | | | | | | | | | again, then run tcctest.c Just like with test[123] add their test[123]b variants. After previous 3 patchs all test pass here on Debian GNU/Linux on i385 with gcc-4.7 with or without memory randomization turned on.
| * lib/bcheck: Fix code typo in __bound_delete_region()Kirill Smelkov2012-12-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We were calling get_page() with t2 index which is not correct, since get_page() operate on t1 indices. The bug is here from day-1, from 60f781c4 (first version of bounds checker) and show as a crash in __bound_delete_region() at program exit: $ ./tcc -B. -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -b -run -DONE_SOURCE \ ./tcc.c -B. -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -run -DONE_SOURCE \ ./tcc.c -B. -run tests/tcctest.c (lot's of correct output from tcctest) Runtime error: dereferencing invalid pointer at 0xa7c21cc4 __bound_delete_region() by (nil) ??? Segmentation fault The fix is simple - last page should be get through t1_end, like it is done in __bound_new_region(). After this patch, tcc is being able to compile itself with -b, then compile itself again and run tcctest with correct output. Tests follow.
| * lib/bcheck: Don't assume heap goes right after bssKirill Smelkov2012-12-091-6/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | At startup __bound_init() wants to mark malloc zone as invalid memory, so that any access to memory on heap, not allocated through malloc be invalid. Other pages are initialized as empty regions, access to which is not treated as invalid by bounds-checking. The problem is code incorrectly assumed that heap goes right after bss, and that is not correct for two cases: 1) if we are running from `tcc -b -run`, program text data and bss will be already in malloced memory, possibly in mmaped region insead of heap, and marking memory as invalid from _end will not cover heap and probably wrongly mark correct regions. 2) if address space randomization is turned on, again heap does not start from _end, and we'll mark as invalid something else instead of malloc area. For example with the following diagnostic patch ... diff --git a/tcc.c b/tcc.c index 5dd5725..31c46e8 100644 --- a/tcc.c +++ b/tcc.c @@ -479,6 +479,8 @@ static int parse_args(TCCState *s, int argc, char **argv) return optind; } +extern int _etext, _edata, _end; + int main(int argc, char **argv) { int i; @@ -487,6 +489,18 @@ int main(int argc, char **argv) int64_t start_time = 0; const char *default_file = NULL; + void *brk; + + brk = sbrk(0); + + fprintf(stderr, "\n>>> TCC\n\n"); + fprintf(stderr, "etext:\t%10p\n", &_etext); + fprintf(stderr, "edata:\t%10p\n", &_edata); + fprintf(stderr, "end:\t%10p\n", &_end); + fprintf(stderr, "brk:\t%10p\n", brk); + fprintf(stderr, "stack:\t%10p\n", &brk); + + fprintf(stderr, "&errno: %p\n", &errno); s = tcc_new(); output_type = TCC_OUTPUT_EXE; diff --git a/tccrun.c b/tccrun.c index 531f46a..25ed30a 100644 --- a/tccrun.c +++ b/tccrun.c @@ -91,6 +91,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) int (*prog_main)(int, char **); int ret; + fprintf(stderr, "\n\ntcc_run() ...\n\n"); + if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) return -1; diff --git a/lib/bcheck.c b/lib/bcheck.c index ea5b233..8b26a5f 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -296,6 +326,8 @@ static void mark_invalid(unsigned long addr, unsigned long size) start = addr; end = addr + size; + fprintf(stderr, "mark_invalid %10p - %10p\n", (void *)addr, (void *)end); + t2_start = (start + BOUND_T3_SIZE - 1) >> BOUND_T3_BITS; if (end != 0) t2_end = end >> BOUND_T3_BITS; ... Look how memory is laid out for `tcc -b -run ...`: $ ./tcc -B. -b -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -run \ -DONE_SOURCE ./tcc.c -B. -c x.c >>> TCC etext: 0x8065477 edata: 0x8070220 end: 0x807a95c brk: 0x807b000 stack: 0xaffff0f0 &errno: 0xa7e25688 tcc_run() ... mark_invalid 0xfff80000 - (nil) mark_invalid 0xa7c31d98 - 0xafc31d98 >>> TCC etext: 0xa7c22767 edata: 0xa7c2759c end: 0xa7c31d98 brk: 0x8211000 stack: 0xafffeff0 &errno: 0xa7e25688 Runtime error: dereferencing invalid pointer ./tccpp.c:1953: at 0xa7beebdf parse_number() (included from ./libtcc.c, ./tcc.c) ./tccpp.c:3003: by 0xa7bf0708 next() (included from ./libtcc.c, ./tcc.c) ./tccgen.c:4465: by 0xa7bfe348 block() (included from ./libtcc.c, ./tcc.c) ./tccgen.c:4440: by 0xa7bfe212 block() (included from ./libtcc.c, ./tcc.c) ./tccgen.c:5529: by 0xa7c01929 gen_function() (included from ./libtcc.c, ./tcc.c) ./tccgen.c:5767: by 0xa7c02602 decl0() (included from ./libtcc.c, ./tcc.c) The second mark_invalid goes right after in-memory-compiled program's _end, and oops, that's not where malloc zone is (starts from brk), and oops again, mark_invalid covers e.g. errno. Then compiled tcc is crasshing by bcheck on errno access: 1776 static void parse_number(const char *p) 1777 { 1778 int b, t, shift, frac_bits, s, exp_val, ch; ... 1951 *q = '\0'; 1952 t = toup(ch); 1953 errno = 0; The solution here is to use sbrk(0) as approximation for the program break start instead of &_end: - if we are a separately compiled program, __bound_init() runs early, and sbrk(0) should be equal or very near to start_brk (in case other constructors malloc something), or - if we are running from under `tcc -b -run`, sbrk(0) will return start of heap portion which is under this program control, and not mark as invalid earlier allocated memory. With this patch `tcc -b -run tcc.c ...` succeeds compiling above small-test program (diagnostic patch is still applied too): $ ./tcc -B. -b -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -run \ -DONE_SOURCE ./tcc.c -B. -c x.c >>> TCC etext: 0x8065477 edata: 0x8070220 end: 0x807a95c brk: 0x807b000 stack: 0xaffff0f0 &errno: 0xa7e25688 tcc_run() ... mark_invalid 0xfff80000 - (nil) mark_invalid 0x8211000 - 0x10211000 >>> TCC etext: 0xa7c22777 edata: 0xa7c275ac end: 0xa7c31da8 brk: 0x8211000 stack: 0xafffeff0 &errno: 0xa7e25688 (completes ok) but running `tcc -b -run tcc.c -run tests/tcctest.c` sigsegv's - that's the plot for the next patch.
| * Make tcc work after self-compiling with bounds-check enabledKirill Smelkov2012-12-093-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For vstack Fabrice used the trick to initialize vtop to &vstack[-1], so that on first push, vtop becomes &vstack[0] and a value is also stored there - everything works. Except that when tcc is compiled with bounds-checking enabled, vstack - 1 returns INVALID_POINTER and oops... Let's workaround it with artificial 1 vstack slot which will not be used, but only serve as an indicator that pointing to &vstack[-1] is ok. Now, tcc, after being self-compiled with -b works: $ ./tcc -B. -o tccb -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" tcc.c -ldl $ cd tests $ ../tcc -B.. -run tcctest.c >1 $ ../tccb -B.. -run tcctest.c >2 $ diff -u 1 2 and note, tcc's compilation speed is not affected: $ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c before: 8270 idents, 47221 lines, 1527730 bytes, 0.152 s, 309800 lines/s, 10.0 MB/s after: 8271 idents, 47221 lines, 1527733 bytes, 0.152 s, 310107 lines/s, 10.0 MB/s But note, that `tcc -b -run tcc` is still broken - for example it crashes on $ cat x.c double get100 () { return 100.0; } $ ./tcc -B. -b -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -run \ -DONE_SOURCE ./tcc.c -B. -c x.c Runtime error: dereferencing invalid pointer ./tccpp.c:1953: at 0xa7beebdf parse_number() (included from ./libtcc.c, ./tcc.c) ./tccpp.c:3003: by 0xa7bf0708 next() (included from ./libtcc.c, ./tcc.c) ./tccgen.c:4465: by 0xa7bfe348 block() (included from ./libtcc.c, ./tcc.c) ./tccgen.c:4440: by 0xa7bfe212 block() (included from ./libtcc.c, ./tcc.c) ./tccgen.c:5529: by 0xa7c01929 gen_function() (included from ./libtcc.c, ./tcc.c) ./tccgen.c:5767: by 0xa7c02602 decl0() (included from ./libtcc.c, ./tcc.c) that's because lib/bcheck.c runtime needs more fixes -- see next patches.
* | Detect ARM CPU version in configureThomas Preud'homme2012-12-042-9/+16
| | | | | | | | | | Instead of guessing the ARM CPU version to compile for from tcc.h, we now detect it in configure and output the value in config.h
* | Fix OABI calling conventionThomas Preud'homme2012-11-281-3/+7
|/ | | | | | OABI calling convention was broken since the addition of the hardfloat calling convention in commit 7f6095bfec82b178084b22b33941d4f06155e514. This commit fixes the breakage.
* arm-gen.c: Invalid operator test always falseThomas Preud'homme2012-11-281-1/+1
| | | | | Invalid operator test is always false in gen_opf for arm (found with cppcheck). This patch fixes the issue.
* tests: btest should only run on targets supporting bcheckKirill Smelkov2012-11-241-0/+5
| | | | | | | | | | | | After 40a54c43 (Repair bounds-checking runtime), and in particular 5d648485 (Now btest pass!) `make test` was broken on ARCH != i386, because I've changed btest to unconditionally run on all arches. But bounds-checking itsels is only supported on i386 and oops... Fix it. Reported-by: Thomas Preud'homme <robotux@celest.fr>
* Update .gitignoreKirill Smelkov2012-11-221-0/+6
| | | | | | | | | | | | | | | | The following files were not ignored (produced by build on i386 with --enable-cross): arm-eabi-tcc arm-fpa-ld-tcc arm-fpa-tcc arm-vfp-tcc c67-tcc i386-win32-tcc lib/i386-win32/ lib/x86_64-win32/ x86_64-tcc x86_64-win32-tcc