GCC_MAJOR may be set even is $CC not realy gcc (but i.e. clang, which (as
of 3.1) requires an addtional CFLAG to accept the non portable (gnuisms all
over the place; try to cimpile tcc with Sun^HOracle, Intel, Pathscale, ...
compiler) code).
- except for CONFIG_SYSROOT and CONFIG_TCCDIR
Strictly neccessary it is only for CONFIG_MULTIARCHDIR
because otherwise if it's in config.h it is impossible to
leave it undefined.
But it is also nicer not to use these definitions for
cross-compilers.
- Also:
lib/Makefile : include ../Makefile for CFLAGS
lib/libtcc1.c : fix an issue compiling tcc with tcc on x64
- add quotes: eval opt=\"$opt\"
- use $source_path/conftest.c for OOT build
- add fn_makelink() for OOT build
- do not check lddir etc. on Windows/MSYS
- formatting
config-print.c
- rename to conftest.c (for consistency)
- change option e to b
- change output from that from "yes" to "no"
- remove inttypes.h dependency
- simpify version output
Makefile:
- improve GCC warning flag checks
tcc.h:
- add back default CONFIG_LDDIR
- add default CONFIG_TCCDIR also (just for fun)
tccpp.c:
- fix Christian's last warning
tccpp.c: In function ‘macro_subst’:
tccpp.c:2803:12: warning: ‘*((void *)&cval+4)’ is used uninitialized
in this function [-Wuninitialized]
That the change fixes the warning doesn't make sense but anyway.
libtcc.c:
- tcc_error/warning: print correct source filename/line for
token :paste: (also inline :asm:)
lddir and multiarch logic still needs fixing.
This replaces -> use instead:
-----------------------------------
- tcc_set_linker -> tcc_set_options(s, "-Wl,...");
- tcc_set_warning -> tcc_set_options(s, "-W...");
- tcc_enable_debug -> tcc_set_options(s, "-g");
parse_args is moved to libtcc.c (now tcc_parse_args).
Also some cleanups:
- reorder TCCState members
- add some comments here and there
- do not use argv's directly, make string copies
- use const char* in tcc_set_linker
- tccpe: use fd instead of fp
tested with -D MEM_DEBUG: 0 bytes left
tests/Makefile:
- print-search-dirs when 'hello' fails
- split off hello-run
win32/include/_mingw.h:
- fix for compatibility with mingw headers
(While our headers in win32 are from mingw-64 and don't have
the problem)
tiny_libmaker:
- don't use "dangerous" mktemp
Should fix some warnings wrt. access out of array bounds.
tccelf.c: fix "static function unused" warning
x86_64-gen.c: fix "ctype.ref uninitialzed" warning and cleanup
tcc-win32.txt: remove obsolete limitation notes.
Also:
- fix "make tcc_p" (profiling version)
- remove old gcc flags:
-mpreferred-stack-boundary=2 -march=i386 -falign-functions=0
- remove test "hello" for Darwin (cannot compile to file)
With:
tcc -g hello.c
gdb a.out
b main
gdb refused to know "main" because of broken dwarf info.
This partially reverts commit 0d598aca08.
I don't remember what the problem was but it was the wrong way
to fix it.
tests:
- add "hello" to test first basic compilation to file/memory
- add "more" test (tests2 suite)
- remove some tests
tests2:
- move into tests dir
- Convert some files from DOS to unix LF
- remove 2>&1 redirection
win32:
- tccrun.c: modify exception filter to exit correctly (needed for btest)
- tcctest.c: exclude weak_test() (feature does not exist on win32)
Fix initialization of args_size before doing register allocation.
When adding hardfloat calling convention the initialization stopped
being performed when !defined (TCC_ARM_EABI).
Add tcc.c as a prerequesite of the %-tcc$(EXESUF) target and compile $<
instead of tcc.c to make sure tcc.c is search in directories specified
by VPATH.
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 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 !
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.
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
--------
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.
Not wise if stddef.h was already included. This is related to commit
3aa26a794e
Instead hack stddef.h to have identical definition and thus
avoid the issue mentionned there.
This reverts commit 63193d1794.
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.
This commit revert commit 061b5799cc 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.
This replaces commit 3d409b0889
- 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
- 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)
* 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.
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
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.
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.
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.
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.
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>
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
A line in gfunc_call in arm-gen.c is referencing vfpr unconditionally.
Yet, this function is only available when TCC_ARM_VFP is set. While this
code is only triggered when TCC_ARM_VFP, it fails at compile time. This
commit fix the problem.
TCC_ARM_EABI should be defined when compiling with hardfloat calling
convention. This commit rework the Makefile to distinguish between
calling convention and multiarch and define TCC_ARM_EABI when hardfloat
calling convention is used. The result is to first guess the calling
convention and then add the multiarch triplet if necessary.
Continuing d6072d37 (Add __builtin_frame_address(0)) implement
__builtin_frame_address for levels greater than zero, in order for
tinycc to be able to compile its own lib/bcheck.c after
cffb7af9 (lib/bcheck: Prevent __bound_local_new / __bound_local_delete
from being miscompiled).
I'm new to the internals, and used the most simple way to do it.
Generated code is not very good for levels >= 2, compare
gcc tcc
level=0 mov %ebp,%eax lea 0x0(%ebp),%eax
level=1 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
level=2 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
mov (%eax),%eax mov %eax,-0x10(%ebp)
mov -0x10(%ebp),%eax
mov (%eax),%eax
level=3 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
mov (%eax),%eax mov (%eax),%ecx
mov (%eax),%eax mov (%ecx),%eax
But this is still an improvement and for bcheck we need level=1 for
which the code is good.
For the tests I had to force gcc use -O0 to not inline the functions.
And -fno-omit-frame-pointer just in case.
If someone knows how to improve the generated code - help is
appreciated.
Thanks,
Kirill
Cc: Michael Matz <matz@suse.de>
Cc: Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
This option does not exist in gcc 4.3 and earlier, and it breaks the build on
systems with older compilers. The makefile has been enhanced to test for the
version and adds it only if a newer compiler is detected.
On this weekend a thought came to me again that tinycc could be used for
scripting. Only its bounds-checking mode turned out to be broken, which
is a pity because bounds-checking is sometimes handy especially for
quickly written scripts.
Since tinycc is one of those small beautiful things, seldomly happening
in our times, I couldn't resist trying to fix it.
Thanks,
Kirill
* bcheck:
Now btest pass!
lib/bcheck: Prevent __bound_local_new / __bound_local_delete from being miscompiled
lib/bcheck: Prevent libc_malloc/libc_free etc from being miscompiled
On i386 and gcc-4.7 I found that __bound_local_new was miscompiled -
look:
#ifdef __i386__
/* return the frame pointer of the caller */
#define GET_CALLER_FP(fp)\
{\
unsigned long *fp1;\
__asm__ __volatile__ ("movl %%ebp,%0" :"=g" (fp1));\
fp = fp1[0];\
}
#endif
/* called when entering a function to add all the local regions */
void FASTCALL __bound_local_new(void *p1)
{
unsigned long addr, size, fp, *p = p1;
GET_CALLER_FP(fp);
for(;;) {
addr = p[0];
if (addr == 0)
break;
addr += fp;
size = p[1];
p += 2;
__bound_new_region((void *)addr, size);
}
}
__bound_local_new:
.LFB40:
.cfi_startproc
pushl %esi
.cfi_def_cfa_offset 8
.cfi_offset 6, -8
pushl %ebx
.cfi_def_cfa_offset 12
.cfi_offset 3, -12
subl $8, %esp // NOTE prologue does not touch %ebp
.cfi_def_cfa_offset 20
#APP
# 235 "lib/bcheck.c" 1
movl %ebp,%edx // %ebp -> fp1
# 0 "" 2
#NO_APP
movl (%edx), %esi // fp1[0] -> fp
movl (%eax), %edx
movl %eax, %ebx
testl %edx, %edx
je .L167
.p2align 2,,3
.L173:
movl 4(%ebx), %eax
addl $8, %ebx
movl %eax, 4(%esp)
addl %esi, %edx
movl %edx, (%esp)
call __bound_new_region
movl (%ebx), %edx
testl %edx, %edx
jne .L173
.L167:
addl $8, %esp
.cfi_def_cfa_offset 12
popl %ebx
.cfi_restore 3
.cfi_def_cfa_offset 8
popl %esi
.cfi_restore 6
.cfi_def_cfa_offset 4
ret
here GET_CALLER_FP() assumed that its using function setups it's stack
frame, i.e. first save, then set %ebp to stack frame start, and then it
has to do perform two lookups: 1) to get current stack frame through
%ebp, and 2) get caller stack frame through (%ebp).
And here is the problem: gcc decided not to setup %ebp for
__bound_local_new and in such case GET_CALLER_FP actually becomes
GET_CALLER_CALLER_FP and oops, wrong regions are registered in bcheck
tables...
The solution is to stop using hand written assembly and rely on gcc's
__builtin_frame_address(1) to get callers frame stack(*). I think for the
builtin gcc should generate correct code, independent of whether it
decides or not to omit frame pointer in using function - it knows it.
(*) judging by gcc history, __builtin_frame_address was there almost
from the beginning - at least it is present in 1992 as seen from the
following commit:
http://gcc.gnu.org/git/?p=gcc.git;a=commit;h=be07f7bdbac76d87d3006c89855491504d5d6202
so we can rely on it being supported by all versions of gcc.
In my environment the assembly of __bound_local_new changes as follows:
diff --git a/bcheck0.s b/bcheck1.s
index 4c02a5f..ef68918 100644
--- a/bcheck0.s
+++ b/bcheck1.s
@@ -1409,20 +1409,17 @@ __bound_init:
__bound_local_new:
.LFB40:
.cfi_startproc
- pushl %esi
+ pushl %ebp // NOTE prologue saves %ebp ...
.cfi_def_cfa_offset 8
- .cfi_offset 6, -8
+ .cfi_offset 5, -8
+ movl %esp, %ebp // ... and reset it to local stack frame
+ .cfi_def_cfa_register 5
+ pushl %esi
pushl %ebx
- .cfi_def_cfa_offset 12
- .cfi_offset 3, -12
subl $8, %esp
- .cfi_def_cfa_offset 20
-#APP
-# 235 "lib/bcheck.c" 1
- movl %ebp,%edx
-# 0 "" 2
-#NO_APP
- movl (%edx), %esi
+ .cfi_offset 6, -12
+ .cfi_offset 3, -16
+ movl 0(%ebp), %esi // stkframe -> stkframe.parent -> fp
movl (%eax), %edx
movl %eax, %ebx
testl %edx, %edx
@@ -1440,13 +1437,13 @@ __bound_local_new:
jne .L173
.L167:
addl $8, %esp
- .cfi_def_cfa_offset 12
popl %ebx
.cfi_restore 3
- .cfi_def_cfa_offset 8
popl %esi
.cfi_restore 6
- .cfi_def_cfa_offset 4
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
ret
.cfi_endproc
i.e. now it compiles correctly.
Though I do not have x86_64 to test, my guess is that
__builtin_frame_address(1) should work there too. If not - please revert
only x86_64 part of the patch. Thanks.
Cc: Michael Matz <matz@suse.de>
On i386 and gcc-4.7 I found that libc_malloc was miscompiled - look:
static void *libc_malloc(size_t size)
{
void *ptr;
restore_malloc_hooks(); // __malloc_hook = saved_malloc_hook
ptr = malloc(size);
install_malloc_hooks(); // saved_malloc_hook = __malloc_hook, __malloc_hook = __bound_malloc
return ptr;
}
.type libc_malloc, @function
libc_malloc:
.LFB56:
.cfi_startproc
pushl %edx
.cfi_def_cfa_offset 8
movl %eax, (%esp)
call malloc
movl $__bound_malloc, __malloc_hook
movl $__bound_free, __free_hook
movl $__bound_realloc, __realloc_hook
movl $__bound_memalign, __memalign_hook
popl %ecx
.cfi_def_cfa_offset 4
ret
Here gcc inlined both restore_malloc_hooks() and install_malloc_hooks()
and decided that
saved_malloc_hook -> __malloc_hook -> saved_malloc_hook
stores are not needed and could be ommitted. Only it did not know
__molloc_hook affects malloc()...
So add compiler barrier to both install and restore hooks functions and
be done with it - the code is now ok:
diff --git a/bcheck0.s b/bcheck1.s
index 5f50293..4c02a5f 100644
--- a/bcheck0.s
+++ b/bcheck1.s
@@ -42,8 +42,24 @@ libc_malloc:
.cfi_startproc
pushl %edx
.cfi_def_cfa_offset 8
+ movl saved_malloc_hook, %edx
+ movl %edx, __malloc_hook
+ movl saved_free_hook, %edx
+ movl %edx, __free_hook
+ movl saved_realloc_hook, %edx
+ movl %edx, __realloc_hook
+ movl saved_memalign_hook, %edx
+ movl %edx, __memalign_hook
movl %eax, (%esp)
call malloc
+ movl __malloc_hook, %edx
+ movl %edx, saved_malloc_hook
+ movl __free_hook, %edx
+ movl %edx, saved_free_hook
+ movl __realloc_hook, %edx
+ movl %edx, saved_realloc_hook
+ movl __memalign_hook, %edx
+ movl %edx, saved_memalign_hook
movl $__bound_malloc, __malloc_hook
movl $__bound_free, __free_hook
movl $__bound_realloc, __realloc_hook
For barrier I use
__asm__ __volatile__ ("": : : "memory")
which is used as compiler barrier by Linux kernel, and mentioned in gcc
docs and in wikipedia [1].
Without this patch any program compiled with tcc -b crashes in startup
because of infinite recursion in libc_malloc.
[1] http://en.wikipedia.org/wiki/Memory_ordering#Compiler_memory_barrier
Revert commit 891dfcdf3f since it assumes
*all* architectures supported by tcc have GOT offsets aligned on 2. A
rework of this commit is being done since without it all PLT entries
grow by 4 bytes.
Since commit c6630ef92a, Call to a veneer
when the final symbol to be reached is thumb is made through a blx
instruction. This is a mistake since veneers are ARM instructions and
should thus be called with a simple bl. This commit prevent the bl ->
blx conversion when a veneer is used.
Source fortification now works correctly : it compiles without warning
except unused result and the resulting tcc is working fine. Hence let's
stop disabling source fortification and hide unused result instead.
Generate PLT thumb stub for an ARM PLT entry only when at least one
Thumb instruction branches to that entry.
Warning: To save space, this commit reuses the bit 0 of entries of
got_offsets array. The GOT offset is thus saved in a 31 bit value.
Make sure to divide by 2 (right shift by 1) an offset before storing it
there and conversely to multiply the value by 2 (left shift by 1) before
using it.
the absence of a clean target in tests2/Makefile make the clean target
in the main Makefile fails to complete. This commit create such a target
which removes the only file created when tests pass successfully.
Add support for relocations R_ARM_THM_JUMP24 and R_ARM_THM_CALL. These
are encountered with gcc when compiling for armv6 or greater with
-mthumb flag and a call (conditional or not) is done.
Currently, VLA are not forbidden for static variable. This leads to
problems even if for fixed-size array when the size expression uses the
ternary operator (cond ? then-value : else-value) because it is parsed
as a general expression which leads to code generated in this case.
This commit solve the problem by forbidding VLA for static variables.
Although not required for the fix, avoiding code generation when the
expression is constant would be a nice addition though.
Introduce ARM version for the target architecture in order to determine
if blx instruction can be used or not. Availability of blx instruction
allows for more scenarii supported in R_ARM_CALL relocation. It should
also be useful when introducing support for the R_ARM_THM_CALL
relocation.
With R_ARM_CALL, if target function is to be entered in Thumb mode, the
relocation is supposed to transform bl in blx. This is not the case
actually so this commit is there to fix it.
Add support for relocations R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS as well
as their Thumb2 counterpart R_ARM_THM_MOVW_ABS_NC and
R_ARM_THM_MOVT_ABS. These are encountered with gcc when compiling for
armv7-a and a data is loaded in a register, either in arm or Thumb2
mode. The first half of the data is loaded with movw ; the second half
is loaded with movt.
We are now compatible with the 0.9,25 version though. A special
value for the second (ptr) argument is used to get the simple
behavior as with the 0.9.24 version.
Arm hardfloat variant uses a different ABI than arm and uses thus a
different multiarch directory for headers and libraries. This commit
detect whether the system uses the hardfloat variant and configure the
multiarch directory accordingly.
The code for shifts is now similar to code for binary arithmetic operations,
except that only the first argument is considered, as required by the ISO C
standard.
The intent is for 'make test' to pass cleanly on each platform, and thus easier
spotting of regressions. Linux is best supported by most tests running and
passing. Mac OSX passes mosts tests that do not make/link with binary files,
due to lack of mach-o file support.
!!! I have very limited knowledge of Windows platform, and cannot comment why
all tests(1) fail. I have posted to newsgroup asking for someone to test
Windows platform.
On 2012-06-26 15:07:57 +0200, Vincent Lefevre wrote:
> ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on
> each of the operands. The type of the result is that of the promoted
> left operand."
I've written a patch (attached). Now the shift problems no longer
occur with the testcase and with GNU MPFR's "make check".
--
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
The tests are taken almost verbatim from the open source project PicoC. It can
be found at https://code.google.com/p/picoc/.
The tests range from very simple/trivial ones to more complicated. My view is
that the more tests the better. Without tests like this I was very reluctant to
make any changes to tcc for the fear of breaking things.
The tests pass on Win32, OSX, Linux x86 and x86_64. One or two tests fail on
each platform due to differences in the runtime library.
Evaluate configure arguments to reproduce autotools behavior. Autotools
actually only expands a few variable and do it at make time but it makes
the change much simpler.
Using /usr/bin/env tcc doesn't work as it was reported. Revert to
using the full path which fails if the user installs tcc in non-default
location. Then again this is just an example.
This reverts commit 27a428cd0f.
I probably broke that myself earlier. In any case parse_args
needs to start with index 0 because it is is used also recursively
to expand the shebang command from scripts such as
#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
which arrives at tcc as only two argv's
"tcc" "-run -L/usr/X11R6/lib -lX11"
When using gcc compiler (as opposed to llvm) to build 32 bit tcc, compiler flags
-mpreferred-stack-boundary=2, -march=i386 and -falign-functions=2 were being
used. -march is redundant as -m32 is already being used. The other two seem to
be corrupting stack. I am not sure why this is the case, as the explanation of
the flags states that only running code size should be affected, but it does.
I think that is is safe to remove these flags altogether for all compilers and
platforms, especially since they are not being used for 64 bit builds. However
I do not want to apply such wide change without agreement from the people on the
mailing list.
Loads of VT_LLOCAL values (which effectively represent saved
addresses of lvalues) were done in VT_INT type, loosing the upper
32 bits. Needs to be done in VT_PTR type.
* Add multiarch directories for arm and i386
* Fix detection of biarch: /lib64/ld-linux-x86-64.so.2 is mandated by
ABI and is thus always present, even if there is no biarch
* Define CONFIG_LDDIR directly with the right value in case of multiarch
instead of defining it to /lib and then redifining it.
This patch fix 2 bugs in CONFIG_LDDIR usage:
* CONFIG_LDDIR used for 2 purposes
there is confusion between the directory to find libraries, crt* files
and headers and the directory in which the program interpreter is.
These two directories are not related. The latter is specified by the
ABI and should not be configurable while the former depends on the
system (single arch, biarch, multiarch). This end a longstanding issue
with amd64 program interpreter later propagated to other architecture
interpreters.
* If multiarch is in effect, then the library directory should be /lib.
/lib64 denotes biarch architecture, everything which is here would be
in /lib/x86_64-linux-gnu instead.
TCCs make dependency generator is incompatible with the GNU
depcomp script which is widely used. For TCC it has to go over
the output of -MD, (it detects it as ICC compatible), but the
sed commands it uses are confused by tabs in the output, so that
some rewrites aren't done.
Those tabs will then finally confuse make itself when the
generated .d files are included. It reads them as goal commands
(leading tab), and is totally lost then.
Short of changing depcomp (hard because distributed with all kinds
of software), simply emit spaces for -MD.
Sometimes the result of a comparison is not directly used in a jump,
but in arithmetic or further comparisons. If those further things
do a vswap() with the VT_CMP as current top, and then generate
instructions for the new top, this most probably destroys the flags
(e.g. if it's a bitfield load like in the example).
vswap() must do the same like vsetc() and not allow VT_CMP vtops
to be moved down.
This matters when sizeof is directly used in arithmetic,
ala "uintptr_t t; t &= -sizeof(long)" (for alignment). When sizeof
isn't size_t (as it's specified to be) this masking will truncate
the high bits of the uintptr_t object (if uintptr_t is larger than
uint).
This needs to be accepted:
typedef int foo;
void f (void) { foo: return; }
namespaces for labels and types are different. The problem is that
the block parser always tries to find a decl first and that routine
doesn't peek enough to detect this case. Needs some adjustments
to unget_tok() so that we can call it even when we already called
it once, but next() didn't come around restoring the buffer yet.
(It lazily does so not when the buffer becomes empty, but rather
when the next call detects that the buffer is empty, i.e. it requires
two next() calls until the unget buffer gets switched back).
When offsetted addresses of global non-static data are computed
multiple times in the same statement the x86_64 backend uses
gen_gotpcrel with offset, which implements an add insn on the
register given. load() uses the R member of the to-be-loaded
value, which doesn't yet have a reg assigned in all cases.
So use the register we're supposed to load the value into as
that register.
The first loop setting up struct arguments must not remove
elements from the vstack (via vtop--), as gen_reg needs them to
potentially evict some argument still held in registers to stack.
Swapping the arg in question to top (and back to its place) also
simplifies the vstore call itself, as not funny save/restore
or some "non-existing" stack elements need to be done.
Generally for a stack a vop-- operation conceptually clobbers
that element, so further references to it aren't allowed anymore.
Removes a premature optimization of char/short loads
rewriting the source type. It did so also for bitfield
loads, thereby removing all the shifts/maskings.
(cond ? 0 : ptr)->member wasn't handled correctly. If one arm
is a null pointer constant (which also can be a pointer) the result
type is that of the other arm.
- tests/Makefile:
fix commit de54586d5b
This hunk it unrelated to the other changes (which are about MacOSX).
It is not useful and partially wrong. Optional tests are meant to
stay optional, btest would work only for i386
- tcc.h:
fix commit c52d79605a by unknown
The message says it's for MINTW but the patch has obviously
no effect for MINGW (which defines __GNUC__). However the patch
seems useful for MSC which however needs _strto(u)i64 with underscore.
- Makefile:
fix commit 5280293d6b
Do not build tcc.o with -DONE_SOURCE because we finally build tcc
from tcc.o and libtcc.a/so
- remove redunant else branch
- zero-terminate linker_arg
- declare cstr_xxx as PUB_FUNC
(which are functions used in tcc.c but not in the libtcc API.
Useful for a tcc(.exe) that uses the libtcc.(so/dll))
- while at it, export PUB_FUNCs from dll
This reverts commit 1c11b857fe.
On windows, libtcc.c is compiled with ONE_SOURCE and then tcc.c is
linked to it. Thus tcc.c can only use public functions which cstr_* are
not.
elements in linker_arg are used in TCCState structure and must thus not
be freed when option parsing is finished. Declare linker_arg as a global
static variable and free it after tcc_delete has been called on TCCState
structure.
This fix commit 7fb0482a46
ld support arguments to multiple-letter options being passed in two
ways:
* -opt=arg
* -opt arg
libtool generate command line of the second form. This commit add
support for the second form so that libtool works with tcc. The way it
is done is to concatenate all -Wl options into one and then pass it to
set_linker.
Other tests still have issues, currently with weak linking.
One of the primary stumbling blocks on OSX is the lack of support for
mach-o binaries. Therefore all tcc usage on OSX has to be limited to elf
binaries, presumably produced by tcc itself.
Therefore I had to enable building of tiny_libmaker for OSX. Then changed
the make to use tcc and tiny_libmaker to compile the tcclib1.
In order to compile the tests, specifically the parts that use weak linking,
I have had to define MACOSX_DEPLOYMENT_TARGET to 10.2, which seems like a
hack, but extensive searching seems to indicate that this is the only way
to make apple gcc allow weak linking. Using any other value, bigger or smaller
breaks weak linking.
Also added _ANSI_SOURCE define required by some OSX headers, and some cosmetic
gitignore changes. I believe these changes should not impact other platforms.
See also commit 9527c4949f
On x86_64 we need to extend the reg_classes array because load()
is called for (at least) R11 too, which was not part of reg_classes
previously.
Modify tcc to accept convert full 64bits of specified text section
when converting on Win64. Write high bytes to the elf section address
as well. This allows creation of elf binaries located in offsets using
full 64 bit addresses.
Signed-off-by: Andrew Mulbrook <andrew262@gmail.com>
Since commit 9b09fc3 ("Add support of asm label for functions",
05-09-2010) tcc has had the capability to rename functions at the
assembly level. This capability was subsequently used by commit
2596273 ("Add support for __REDIRECT_NTH needed with eglibc",
11-09-2010) to redirect long double functions on platforms which
did not support long double.
Here we add the companion macro __REDIRECT which is used (along
with __REDIRECT_NTH) in the glibc headers on Linux to support the
Large File API (when _FILE_OFFSET_BITS is set to 64).
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
This changeset attempts to fix a few problems when giving using
the high 32bits of a 64bit section offset. There are likely more
issues (or perhaps regressions) lurking in the muck here. In general,
this moves a few data type declarations to use uplong. Also, add
support for 64bit mingw32 building under cygwin. Because native
types are used for 64 bit offsets, this won't fix challenges with
cross compiling from 32bit -> 64bit.
Tested under cygwin, against binary compiled with
-Wl,-Ttext=0xffffff8000000000
Signed-off-by: Andrew Mulbrook <andrew262@gmail.com>
to the appropriate CFLAGS. In addition, memory hooks are very different
on OSX, so build of bcheck.c had to be disabled for now.
Change of the CFLAGS does affect builds on other platforms, and this needs
to be tested.
Applied patch found on stackoverflow (link below). I also found some
related changes that looked like logically needed. The stackoverflow
changes addressed only two registers which were breaking a compile.
However reading the code in the same file shows two other register
accesses that, while not breaking the build, should have the same fix.
http://stackoverflow.com/questions/3712902/problems-compiling-tcc-on-os-x/3713144#3713144
The test driver was changed by changing 'cp -u' into 'cp' as '-u' is not
supported on mac osx.
I found that osx build required the WITHOUT_LIBTCC define. I suspect the
reason for this is tcc unability to handle mach-o files. In order to
properly address this I had to change 'configure' to propagate target os
name to Makefile.
Current state is that simple tests work, but not the whole 'make test'
suite runs.
To the best of my knowledge, these changes should not impact other
platforms.
Remove the previous logic to link a named file with a loader script by
using tcc_add_dll instead. Hence, all files can be linked, not only
files ending in .so/.def.
TinyCC fails to link correctly to libraries when both R_ARM_PLT32 and
R_ARM_GOT32 relocation to a same symbol exist (see
http://lists.nongnu.org/archive/html/tinycc-devel/2010-05/msg00032.html
for more details).
The patch marks all undefined weak symbols found in external libraries
as strong. The value of all remaining weak symbols is set to zero just
before the section is output.
Note by Thomas Preud'homme: it's been 2 months in Debian without any new
bug report, hence commiting.
- use {B} to substitute tcc_lih_path (instead of \b)
- expand CONFIG_TCC_CRTPREFIX in CONFIG_TCC_LIBPATHS
which fixes duplicate CONFIG_SYSROOT.
- put default CONFIG_SYSROOT ("") into tcc.h
- remove hack from commit db6fcce78f
because $(tccdir)/include is already in sysincludes
- configure: error out for unrecognized options.
- win32/build-tcc.bat: put libtcc into base dir where it will
find lib/include automatically, and build libtcc_test example.
This cleans up the mess from commit
8f98573658
and preceeding.
- make tcc -m64 work on windows
- execvp on windows returns 0 always, replace by spawnvp
- remove bizarre support for i386-win32-tcc -m64
This fixes a bug introduced in commit
8d107d9ffd
that produced wrong code because of interference between
0x10 bits VT_CONST and x86_64-gen.c:TREG_MEM
Also fully zero-pad long doubles on x86-64 to avoid random
bytes in output files which disturb file comparison.
--sysincludepaths=.. specify system include paths, colon separated"
Sets CONFIG_TCC_SYSINCLUDEPATHS
--libpaths=... specify system library paths, colon separated"
Sets CONFIG_TCC_LIBPATHS
--crtprefix=... specify location of crt?.o"
Sets CONFIG_TCC_CRTPREFIX
--elfinterp=... specify elf interpreter"
Sets CONFIG_TCC_ELFINTERP
Also the CONFIG_TCC_XXX were renamed to make them look
more consistent.
Also move the elf_interp definitions to tcc.h.
Add a --multiarch-triplet switch to configure. The switch will allow
files to be search for each default path in path/<triplet> and then
path.
Default paths handled that way:
- CONFIG_TCC_SYSINCLUDE_PATHS
- CONFIG_TCC_LIBPATH
- path to crt*.o
- path to libgcc_s.so.1
Path missing: elf interpreter path (will be handled in another commit)
This allows passing colon separated paths to
tcc_add_library_path
tcc_add_sysinclude_path
tcc_add_include_path
Also there are new configure variables
CONFIG_TCC_LIBPATH
CONFIG_TCC_SYSINCLUDE_PATHS
which define the lib/sysinclude paths all in one and can
be overridden from configure/make
For TCC_TARGET_PE semicolons (;) are used as separators
Also, \b in the path string is replaced by s->tcc_lib_path
(CONFIG_TCCDIR rsp. -B option)
Since no code should be generated outside a function, force expr_cond to
only consider constant expression when outside a function since the
generic code can generate some code.
Basically, with:
typedef __attribute__((aligned(16))) struct _xyz {
...
} xyz, *pxyz;
we want the struct aligned but not the pointer.
FIXME: This patch is a hack, waiting for someone in the knowledge
of correct __attribute__ semantics.
This was already possible using
make NOTALLINONE=1
and is now the default.
To build as previously from one big source, use
make ONE_SOURCE=1
Cross compilers are still build from one source because using
separate objects requires separate build directories one per
platform which currently is not (yet) supported by the makefile.
We could probably use gnu-makeish target variables like
$(I386_CROSS): OUTDIR=build/i386
$(X64_CROSS): OUTDIR=build/x86-64
and so on ...
Also NEED_FLOAT_TYPES for arm-gen is removed. It was about
variables that are referenced from outside (libtcc, tccgen).
We could declare them in tcc.h (as with reg_classes) or have
them twice in arm-gen.c. I chose option 2.
array_test is declared and called with no parameters but defined with
one parameter. Compilation succeed (definition is after the use so the
compiler consider the declaration) as well as link (the function exist
and has the right name) but running the test segfault on i386 platforms.
This patch moves the parameter to local variable. If the intention was
to call it with an array parameter then feel free to fix it again.
which live in msvcrt.dll and need __declspec(import) which
works by now.
Also:
- _mingw.h: conditionally define WIN32_LEAN_AND_MEAN
- malloc.h: don't undef alloca
* Rename tcc_split_path_components
* Move tcc_split_path below memory wrapper section
* Ident tcc_split_path by 4
* Remove prefix and suffix clutter in tcc_split_path
* Don't dereference beyond the end of the search paths string
Add the possibility to search headers in several subdirectories of
/usr/local/include and /usr/include. A possible use case would be for
tcc to search for headers in /usr/local/include/x86_64-linux-gnu,
/usr/local/include, /usr/include/x86_64-linux-gnu and /usr/include in
turn.
By default, tcc search libraries in /lib and /usr/local/lib while crt*.o
files are searched in /usr/lib and ld.so is searched in /lib.
Unfortunetely the path are hardcoded in source code. This patch allow
tcc to look in an other directory and also to look in extra directories.
It's then possible to make tcc search libraries in /lib/x86_64-linux-gnu
and /usr/local/lib/x86_64-linux-gnu while crt*.o files are searched in
/usr/lib/x86_64-linux-gnu and ld.so is searched in
/lib/x86_64-linux-gnu.
Use @BINDIR@ in shebang of examples to put the right path on the target
system. That is, use #!/usr/local/bin/tcc if tcc is installed in /usr/local/bin
and #!/usr/bin/tcc if tcc is installed in /usr/bin/tcc.
* Set CFLAGS entirely in configure if not already set.
* Compile bcheck.c with the same flags as the other source files
* Don't strip binaries by default (GB are cheap now) but provide a
--strip-binaries option in configure script.
* Mention the various ARM improvement
* Make changelog consistent with regards to initial capital letters
* Fix credits for VLA
* Fix entry about asm label (variable are also supported)
VLA inserts a call to alloca via enum TOK_alloca, but TOK_alloca
only exists on I386 and X86_64 targets. This patch just emits an
error at compile-time if someone tries to compile some VLA code
for a TOK_alloca-less target. The best solution might be to just
push the problem to link-time, since the existence-or-not of a
alloca implementation can only be determined by linking. It seems
like just declaring TOK_alloca unconditionally would achieve that,
but for now, this at least gets the cross compilers to build.
I don't know if it makes a difference to gen_op(TOK_PDIV) or not,
but logically the ptr1_is_vla test in TP's VLA patch seems out of
order, where the patch to fix it would be:
------------------------------------------------------------------
@@ -1581,15 +1581,15 @@ ST_FUNC void gen_op(int op)
u = pointed_size(&vtop[-1].type);
}
gen_opic(op);
+ if (ptr1_is_vla)
+ vswap();
/* set to integer type */
#ifdef TCC_TARGET_X86_64
vtop->type.t = VT_LLONG;
#else
vtop->type.t = VT_INT;
#endif
- if (ptr1_is_vla)
- vswap();
- else
+ if (!ptr1_is_vla)
vpushi(u);
gen_op(TOK_PDIV);
} else {
------------------------------------------------------------------
Instead of that patch, which increases the complexity of the code,
this one fixes the problem by just rolling back and retrying with
a simpler approach.
A VLA is not really an array, it's a pointer-to-an-array.
Making this explicit allows us to back out a few parts
of the original VLA patch and paves the way for the next
part of the fix, where a VLA will be stored on the runtime
stack as a pointer-to-an-array, rather than on the compile-
time stack as a Sym*.
test target in Makefile does not depend on tcc.
i'm not sure why, but i can think of at least one
good reason. in my local tree I have it modified
to do so, but somehow inadvertently reverted that
so when i did "make test" before committing, it
didn't actually test my changes. sorry.
previously, tcc would accept a prototype of a function returning
an array, but not giving those functions bodies nor calling them.
it seems that gcc has never supported them, so we should probably
just error out... but it's possible that someone already using
tcc includes some header that contains an unused prototype for
one, so let's continue to support that.
- fix my prev commit:
put declaration above statements to stay c89 compatible
- replace commit by a blank
#define con(a, b) a/**/b
this should yield a b, not ab
We need a ' ' after subst of m in the following case
#define m(name,r) name ## r
#define m0(a,b,c) int m(a,b) c
#define m1(a,b,c) int m(a,b)c
m0(a, b, c);
m1(a, b, c);
To make this the default, enable this line in libtcc.c:tcc_new:
#if defined(TCC_TARGET_PE) && 0
s->leading_underscore = 1;
and then recompile tcc and also libtcc1.a
Add support for asm labels for variables, that is the ability to rename
a variable at assembly level with __asm__ ("newname") appended in
its declaration.
See http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Asm-Labels.html for more
details.
- Fix function assembly label mechanism introduced in commit
9b09fc376e to only accept alternative
name for function declaration.
- merge the code with the one introduced in commit
264a103610.
- Don't memorize token for asm label but directly the asm label.
Error out on static function without file scope and give an explaination
to the user
This is a rewrite of e9406c09a3 but
considering problems raised about static local function pointers in
632ee5a540.
* Disable C99 VLA detection when alloca is unavailable and protect the
new reference to TOK_alloca in decl_initializer in order to compile
and run for architecture without working alloca.
Not all code of C99 VLA is commented as it would required many ifdef
stanza. Just the detection is commented so that VT_VLA is never set
any type and the C99 VLA code is compiled but never called. However
vpush_global_sym(&func_old_type, TOK_alloca) in decl_initializer needs
to be protected by an ifdef stanza as well because it uses TOK_alloca.
* include alloca and C99 VLA tests according to availability of
TOK_alloca instead of relying on the current architecture
TOK_alloca is now available on x86-64 so make put definition of
TOK_alloca outside the BCHECK conditional macro definition but test if
arch is i386 or x86-64. This makes C99 VLA works (understand compile) on
x86-64.
Implement C99 Variable Length Arrays in tinycc:
- Support VLA with multiple level (nested vla)
- Update documentation with regards to VT_VLA
- Add a testsuite in tcctest.c
The problem was partially fixed by Henry in the following patch:
tcc.c: skip -lpthread when -c option specified
But that patch had one brawback: it is sensitive to argument order,
as decision is taken during commandline parsing:
$ tcc -c a.c -o a.o -pthread # 1. works fine
tcc: error: file 'a.c' not found
$ tcc -pthread -c a.c -o a.o # 2. blows
tcc: error: cannot specify libraries with -c
This patch fixes case 2.
Signed-off-by: Sergei Trofimovich <st@anti-virus.by>
- add __builtin_va_arg_types to check how arguments were passed
- move most code of stdarg into libtcc1.c
- remove __builtin_malloc and __builtin_free
- add a test case based on the bug report
(http://www.mail-archive.com/tinycc-devel@nongnu.org/msg03036.html)
- r_addend should be applied for PLT entries as well
- R_X86_64_PLT32 should be handled just like R_X86_64_PC32
- spec says GLOB_DAT and JUMP_SLOT don't need r_addend (not tested)
http://www.x86-64.org/documentation/abi.pdf
Now we can -run ELF objects generated by GCC.
86ffc48129
removed this cp command. However, it was necessary to pass tests on x86-64
because include/stdarg.h is different from GCC's definition on x86-64.
This fixes the i386-win32-tcc cross-compiler on x86-64 linux
platform.
I verified that it produces identical binaries for 'hello_win.exe'
and 'tcc.exe' (tcc compiled by itself) compared to the output of
the native tcc on windows.
Add support for __REDIRECT_NTH as eglibc makes use of this macro to
redirect long double functions to long functions on arch not supporting
long double.
Add support for asm labels for functions, that is the ability to rename
a function at assembly level with __asm__ ("newname") appended in
function declaration.
- Fix a wrong calculation for size of struct
- Handle cases where struct size isn't multple of 8
- Recover vstack after memcpy for pushing struct
- Add a float parameter for struct_assign_test1 to check SSE alignment
This reverts commit 433ecdfc9d.
The patch breaks e.g. with
for ((i = 10); --i;);
In particular to check for a type decl. this is not sufficient:
if (tok < TOK_UIDENT) {
A future approach to c99 loop variables might instead use:
if (parse_btype(...)) {
plus refactor function decl() accordingly.
Hello up there.
I'm trying to change gcc to tcc for faster develpment on slow machines,
and the first obstacle that turned out was lack of dependency generation
on tcc side.
Attached patches try to fix that.
Thanks,
Kirill
* tcc-MD:
.gitignore += tags
tcc: Explicitly require -l<lib> for libraries
Document what tcc_fileextension does
tcc -E: Let output_default be <file>.o instead of a.out
tcc: Draft suppoprt for -MD/-MF options
tcc: Refactor "compute default outfile name" into libtcc function
Add input files/libs and reloc_output switch to TCCState
tcc: Fix typo in error (it's '%s', not '%s)
chmod a-x i386-gen.c
.gitignore += *.o *.a
.cvsignore -> .gitignore
This affectes where `tcc -E -MD file.c` will place generated dependency
information -- previously, for `tcc -E` output_default was a.out, and so
deps were put into a.d .
Avoid this behaviour, by treating `tcc -E` as `tcc -c` with respect to
output_default computation.
This will not hurt anything else (preprocessor outputs to either stdout,
or to explicitely given (-o <file>) destination, so no default filename
is used here), and on the other hand `tcc -E -MD file.c` now puts
dependencies into file.d (the same behaviour as for gcc -E).
v2:
- restructured condition a bit to make it more clear
Since for upcoming -MD support default _compile_ output file be needed
even when preprocesssing (tcc -E), let's move this code out of one
particular condition block into a common function, so that we could use
it in deps generation code too.
v2:
- As suggested by grischka, moved into libtcc function instead of always
computing near start of main()
- There is a FIXME about how to return result - I don't want to bother
callers with allocating temp buffers, not I think it will be a good
idea to hook default_target to TCCState. Clearly, I'm to used to
things like std::string and python's str...
files[0], and reloc_outpu will be needed for (upcoming in the next
patch) "compute default outfile name" refactored into libtcc function.
Also, since for symmetry and from libification point of view, it makes
some sense to also put all information about what was given as input to
compilation into TCCState, let's not only put files[0], but all
files and all libraries given explicitely by user.
One point: I've used bitfield for reloc_output & trimmed down
output_type to 8 bits so that TCCState stays the same in size, and also
access to output_type is (hopefully) is not slower.
By the way -- as of today, sizeof(TCCState) on i686-pc-linux-gnu is 2884
bytes...
We no longer use CVS, so let's teach Git about what files to ignore...
... though doing `git status` after make + `make test` still gives
untracked content:
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# alloca86-bt.o
# alloca86.o
# bcheck.o
# libtcc.a
# libtcc.o
# libtcc1.a
# libtcc1.o
# tcc.o
See next patch about this stuff.
configure and gcctestsuite.sh shell scripts contains bashisms although being
bourne shell script. This patch fixes the following bashisms:
* Use of $RANDOM variable (replaced by reading in /dev/urandom)
* Use == in tests instead of just =
* Use $[] for arithmetic computation istead of $(())
ARM architecture doesn't have any libtcc1 implementation but tcc load
libtcc1.a in all case. This patch add a conditional preprocessor
instruction to load libtcc1.a only when there is an implementation for
the target architecture.
Make sure alias symbols resolve to the same address in program .bss or .data
section. This ensure for example that if a program reference environ (via an
extern char **environ declaration) and the libc change its value via the
__environ alias after the R_ARCH_COPY relocation have been performed, then
the program will see the new value.
Summary of what was changed or added so far:
These won't work on Win32
* --disable-static option builds libtcca.so.1.0 and associated simlinks.
This replaces libtcca.a, which is a static library with a dynamic one.
* --with-selinux option uses mmap to enable tcc -run to work with Selinux.
* attempt to build tcc1.def on i386 / x86_64 when --enable-cross is used.
If successful, this gets around the "_start not found" or "_winstart not
found" messages when i386-win32-tcc is run on these systems. I say "if"
because it gave me fits of trouble on my system and not all others have
been tested yet. tcc1.def is not a real .def file by the way, but it works,
so it's kind of a dancing bear at this point. We're not concerned that
it's getting the steps wrong. We're just happy it's not eating us for lunch.
* additional make target for lib/tcc1.def on non-win32 builds
tcc1.def was formerly lib/libtcc1.a but has bee made into its
own Makefile target, tcc1.def
* use mv instead of cp on config.h
this fixes a mistake I made which caused Makefile to rebuild
all targets every time
* make links from libtcc.so.1.0 to libtcc.so.1 and libtcc.so
merge more changes from Fedora spec file into Makefile
I did a lot of reading on Makefiles. It should be a lot less hacked now that I got rid of my temporary cross-build script. I had to build i386-win32-tcc as 32 bit in order to use it to build the windows version of libtcc1.a and move that into lib directory. Still testing, but it does build windows fib.exe smoothly now and generates shard lib, libtcc.so.1.0 and test links against it.
on x86_64 using --enable-cross. The easiest way to fix this is
to put -m32 in the Makefile.
Committer: Henry Kroll <henry@comptune.com>
Committer: Henry Kroll <henry@comptune.com>
* Replace the save/load_buffer_state by a dynarray approach:
- Filename and libname are added to a dynarray when first encountered
- Load repeatedly the files in the dynarray until no new undefined
symbol are encountered
* Replace snprintf by sprintf in libname_to_filename
* Use tcc_fileextension in filename_to_libname
* Introduce a tcc_strcpy_part fonction to copy only a subset of a
string
* Move new_undef_syms declaration from tcc.h to tccelf.c
gcc -o libtcc1.o -c lib/libtcc1.c -O2 -Wall
libtcc.c: At top level:
libtcc.c:1063: error: static declaration of 'tcc_add_file_internal' follows non-static declaration
tccelf.c:2915: note: previous implicit declaration of 'tcc_add_file_internal' was here
Signed-off-by: Sergei Trofimovich <st@anti-virus.by>
* search file from INPUT and GROUP commands in the library path in
addition to the current directory
* handle libraries specified by -lfoo options
* Search lib in GROUP command repeatedly
Prefixing $prefix with $(DESTDIR) is an error as it could lead for
example to mandir being equal to $(DESTDIR)$prefix/man where
$prefix itself is equal to $(DESTDIR)/usr/local which make man be equal
to $(DESTDIR)$(DESTDIR)/usr/local/man
Unary expression can start with a parenthesis. Thus, the current test
to detect which sizeof form is being parsed is inaccurate. This patch
makes tcc able to handle things like sizeof (x)[1] where x is declared
as char x[5]; wich is a valid unary expression
Error out with an explicit message when trying to initialize a
character array with something that's not a literal (optionally
enclosed in braces) as per C99 6.7.8:14; thanks to Antti-Juhani
Kaijanaho <ajk@debian.org> who did all the work.
Some patches, to allow tcc to compile asm sources generated by gcc
and help tcc with the autoconf stuff used in Wine
( http://source.winehq.org/git/wine.git/ )
--
By by ... Detlef
Without -Bsymbolic, a symbol/function in a *.so can be overridden
by a symbol/function in the main module.
That is the default search order, but not supported by tcc.
With -Bsymbolic, the linker tries to resolve a symbol/function in
the current module first.
The loader in tcc implements this search order.
We do not distinguish -Bsymbolic and -Bsymbolic-function
--
By by ... Detlef
This enables native unwind semantics with longjmp on
win64 by putting an entry into the .pdata section for
each compiled fuction.
Also, the function now use a fixed stack and store arguments
into X(%rsp) rather than using push.
When storing structs with a memcpy call in vstore(),
so far a needless entry remaining on the vstack
sometimes resulted in an useless store generated by
save_regs() in gfunc_call() for the memcpy routine.
On Sun, Nov 22, 2009 at 05:43:14PM +0100, Luigi Rizzo wrote:
> Hi,
> there is a well known problem with tcc and FreeBSD in the generation
> of elf objects -- see
> http://lists.gnu.org/archive/html/tinycc-devel/2005-07/msg00070.html
>
> Apparently Sergey Lyubka has tried a partial fix to the problem.
> I was wondering if Sergey or someone can post some more detail on
> what needs to be done so we can try to help fixing this issue
I think i have managed to solve the problem and produce
almost valid elf files on FreeBSD. The two patches attached
address a few problems (trying to explain to the
best of my knowledge; i am not very familiar with ELF and
the FreeBSD ELF conventions):
1. ELF file format
tcc produces an ELF executable which is good for linux but
not for FreeBSD. It misses the PHDR section which is almost
mandatory for shared executables, puts in the .dynsym section
some relocation info that FreeBSD expects to be in .got,
and expect the relocation sections to be contiguous.
patch-tccelf.c tries to address the above problem using
conditional sections (so hopefully can be imported upstream)
and also adds the ability to override the name of the dynamic
loader through an environment variable (this is important to
debug tcc).
2. predefined macros
patch-libtcc.c adds/fixes some predefined macros when compiling
on FreeBSD: these are __FreeBSD__ and the usual set of
__i386__ and __unix__ variants.
It also sets __INTEL_COMPILER so we can grab the __aligned
macro from cdefs.h , otherwise many programs would fail
The resulting elf file is still not 100% correct -- if you strip it,
the program will not run (presumably there is some dangling reference).
Other than that, program do seem to run correctly.
It would be nice to integrate these patches in the main repository.
The FreeBSD specific code is in #ifdef so it should not harm
linux users
cheers
luigi
- calling conventions are different:
* only 4 registers
* stack "scratch area" is always reserved
* doubles are mirrored in normal registers
- no GOT or PIC there
Date: Mon, 8 Jun 2009 19:06:56 +0800
From: Soloist Deng <soloist.deng-gmail-com>
Subject: [Tinycc-devel] trying to fix the bug of unclean FPU st(0)
Hi all:
I am using tcc-0.9.25, and the FPU bug brought a big trouble to
me. I read the source and tried to fix it.
Below is my solution.
There are two places where program(`o(0xd9dd)') will generates `fstp
%st(1)': vpop() in tccgen.c:689 and save_reg() in tccgen.c:210.
We should first change both of them to `o(0xd8dd) // fstp %st(0)'.
But these changes are not enough. Let's check the following code.
void foo()
{
double var = 2.7;
var++;
}
Using the changed tcc will generate following machine code:
.text:08000000 public foo
.text:08000000 foo proc near
.text:08000000
.text:08000000 var_18 = qword ptr -18h
.text:08000000 var_10 = qword ptr -10h
.text:08000000 var_8 = qword ptr -8
.text:08000000
.text:08000000 push ebp
.text:08000001 mov ebp, esp
.text:08000003 sub esp, 18h
.text:08000009 nop
.text:0800000A fld L_0
.text:08000010 fst [ebp+var_8]
.text:08000013 fstp st(0)
.text:08000015 fld [ebp+var_8]
.text:08000018 fst [ebp+var_10]
.text:0800001B fstp st(0)
.text:0800001D fst [ebp+var_18]
.text:08000020 fstp st(0)
.text:08000022 fld L_1
.text:08000028 fadd [ebp+var_10]
.text:0800002B fst [ebp+var_8]
.text:0800002E fstp st(0)
.text:08000030 leave
.text:08000031 retn
.text:08000031 foo endp
.text:08000031
.text:08000031 _text ends
--------------------------------------------------
.data:08000040 ; Segment type: Pure data
.data:08000040 ; Segment permissions: Read/Write
.data:08000040 ; Segment alignment '32byte' can not be represented in assembly
.data:08000040 _data segment page public 'DATA' use32
.data:08000040 assume cs:_data
.data:08000040 ;org 8000040h
.data:08000040 L_0 dq 400599999999999Ah
.data:08000048 L_1 dq 3FF0000000000000h
.data:08000048 _data ends
Please notice the code snippet from 0800000A to 08000020
// double var = 2.7; load constant to st(0)
.text:0800000A fld L_0
// double var = 2.7; store st(0) to `var'
.text:08000010 fst [ebp+var_8]
// double var = 2.7; poping st(0) will empty the floating registers stack
.text:08000013 fstp st(0)
After that ,tcc will call `void inc(int post, int c)" in
tccgen.c:2150, and produce 08000015 to 0800001B through the calling
chain (inc ->gv_dup)
// load from `var' to st(0)
.text:08000015 fld [ebp+var_8]
// store st(0) to a temporary location
.text:08000018 fst [ebp+var_10]
// poping st(0) will empty the floating registers stack
.text:0800001B fstp st(0)
And the calling chain
(gen_op('+')->gen_opif('+')->gen_opf('+')->gv(rc=2)->get_reg(rc=2)->save_reg(r=3))
will produce 0800001D to 08000020 .
// store st(0) to a temporary location, but floating stack is empty!
.text:0800001D fst [ebp+var_18]
// poping st(0) will empty the floating registers stack
.text:08000020 fstp st(0)
The `0800001D fst [ebp+var_18]' will store st(0) to a memory
location, but st(0) is empty. That will cause FPU invalid operation
exception(#IE).
Why does tcc do that? Please read `gv_dup' called by `inc' carefully.
Notice these lines:
(1): r = gv(rc);
(2): r1 = get_reg(rc);
(3): sv.r = r;
sv.c.ul = 0;
(4) load(r1, &sv); /* move r to r1 */
(5) vdup();
/* duplicates value */
(6) vtop->r = r1;
(1) let the vtop occupy TREG_ST0, and `r' will be TREG_ST0. (2)
try to get a free floating register,but tcc assume
there is only one, so it wil force vtop goto memory and assign `r1'
with TREG_ST0. When executing (3), it will do nothing
because `r' equals `r1'. (5) duplicates vtop. Then (6) let the new
vtop occupy TREG_ST0, but this will cause problem
because the old vtop has been moved to memory, so the new duplicated
vtop does not reside in TREG_ST0 but also
in memory after that. TREG_ST0 is not occupied but freely availabe
now. `gen_op('+')' need at least one oprand in register,
so it will incorrectly think TREG_ST0 is occupied by vtop and produce
instructions(0800001D and 08000020) to store it to
a temporary memory location.
According program above, if `r' == `r1' it is impossible for the old
vtop to still occupy the `r' register . And `load' will do nothing
too at this condition.
So the `gv_dup' can not promise the semantics that old vtop in one
register and the new duplicated vtop in another register at the same
time.
I changed (6) to
if (r != r1)
{
vtop->r = r1;
}
Then the new generated machine code will be :
.text:08000000 push ebp
.text:08000001 mov ebp, esp
.text:08000003 sub esp, 10h
.text:08000009 nop
.text:0800000A fld L_0
.text:08000010 fst [ebp+var_8]
.text:08000013 fstp st(0)
.text:08000015 fld [ebp+var_8]
.text:08000018 fst [ebp+var_10]
.text:0800001B fstp st(0)
.text:0800001D fld L_1
.text:08000023 fadd [ebp+var_10]
.text:08000026 fst [ebp+var_8]
.text:08000029 fstp st(0)
.text:0800002B leave
.text:0800002C retn
It works well, and will clean the floating registers stack when return.
Finally, I want to know there is any potential problem of this fixing ?
soloist
(Because GNU's alloca.h unconditionally #undef's alloca)
Also, remove gcc specific sections in headers. and
instead change tests such that gcc does not use them.
comparing the filenames as in the #include statement can be
ambiguous if including files are in different directories.
Now caches and checks the really opened filename instead.
The loop constructs to iterate over the non-overlapping, even
positions of two or three bytes in a word were broken.
This patch fixes the loops. It has been verified to generate the
72 combinations for two and the 80 combinations for three bytes.
TCC produces code which is incompatible with GCC for the following code:
printf("%lld\n", (long long)-2147483648);
printf("%lld\n", (long long)-2147483649);
For now, just avoid using the corner value.
- Cast from pointer to long long makes TCC output an error. Use cast to int before we apply shift operation for a pointer value.
- Removed test cases for casts from pointer to char/short because they produce warning.
- Now we use x87's stack top the long double return values.
- Add rc_fret and reg_fret, wrapper functions for RC_FRET and REG_FRET.
- Add a test case to check if strto* works OK.
- Now we can run tcc -run tcc.c successfully, though there are some bugs.
- Remove jmp_table and got_table and use text_section for got and plt entries.
- Combine buffers in tcc_relocate().
- Use R_X86_64_64 instead of R_X86_64_32 for R_DATA_32 (now the name R_DATA_32 is inappropriate...).
- Add got_table in TCCState. This approach is naive and the distance between executable code and GOT can be longer than 32bit.
- Handle R_X86_64_GOTPCREL properly. We use got_table for TCC_OUTPUT_MEMORY case for now.
- Fix load() and store() so that they access global variables via GOT.
We need malloc and free to implement va_start and va_end.
Since malloc and free may be replaced by #define, we add __builtin_malloc and __builtin_free.
- Add a macro TCC_OUTPUT_DLL_WITH_PLT.
-- Now, the DLL with PLT support works only on x86-64, but we may be able to support it on all architectures eventually.
- Define TCC_OUTPUT_DLL_WITH_PLT when target architecture is x86-64.
- Current status (x86-64):
-- Main program should be able to call functions in shared objects.
-- Main program should be able to use global variables in shared objects.
-- Shared objects should be able to call functions in main program.
-- Shared objects can NOT use global variables in main program.
- To fix the last issue, we may need to add support of -fPIC option in our code generator.
Recently I needed to trim storage space on an embedded distro which has
X.
X depend on cpp which is ~8MB in size as shipped in Debian, so the idea
was to remove cpp and use `tcc -E` instead where appropriate.
I've done this with the following 'hack' put inplace of /usr/bin/cpp :
#!/bin/sh -e
TCC=/home/kirr/local/tcc/bin/tcc
last="${!#}"
# hack to distinguish between '... -D...' and '... file'
if test -r "$last"; then
exec $TCC -E "$@"
else
exec $TCC -E "$@" -
fi
But the problem turned out to be in `tcc -E` inability to preserve
spaces between tokens. So e.g. the following ~/.Xresources
XTerm*VT100*foreground: black
...
got translated to
XTerm * VT100 * foreground : black
which is bad, bacause now X don't understand it.
Below is a newbie "fix" for the problem.
It still does not preserve spaces on macro expansion, but since the fix
cures original problem, I think it is at least one step forward.
Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru>
As recently shown in fb0ac2 (s/int/unsigned/ since GCC 4.3.2 produces
code which doesn't stop)
comparing (signed) int variable to 0x80000000 is not idea for x86_64.
This is not a good idea for x86_32 either, because GCC 4.3.2 (the one in
Debian Lenny) rightly assumes that a signed int could be never
0x80000000, and thus removes the check from
while (b != 0x80000000) {
...
completely.
If we want this check, we need b to be always 'unsigned'
Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru>
Most change was done in #ifdef TCC_TARGET_X86_64. So, nothing should be broken by this change.
Summary of current status of x86-64 support:
- produces x86-64 object files and executables.
- the x86-64 code generator is based on x86's.
-- for long long integers, we use 64bit registers instead of tcc's generic implementation.
-- for float or double, we use SSE. SSE registers are not utilized well (we only use xmm0 and xmm1).
-- for long double, we use x87 FPU.
- passes make test.
- passes ./libtcc_test.
- can compile tcc.c. The compiled tcc can compile tcc.c, too. (there should be some bugs since the binary size of tcc2 and tcc3 is differ where tcc tcc.c -o tcc2 and tcc2 tcc.c -o tcc3)
- can compile links browser. It seems working.
- not tested well. I tested this work only on my linux box with few programs.
- calling convention of long-double-integer or struct is not exactly the same as GCC's x86-64 ABI.
- implementation of tcc -run is naive (tcc -run tcctest.c works, but tcc -run tcc.c doesn't work). Relocating 64bit addresses seems to be not as simple as 32bit environments.
- shared object support isn't unimplemented
- no bounds checker support
- some builtin functions such as __divdi3 aren't supported
- Use REL_SECTION_FMT instead of ".rel%s".
- Use PTR_SIZE instead of sizeof(int) for GOT entries.
- Use sizeof(ElfW(Dyn)) instead of magic number 8.
- Use TCC_ELFCLASS instead of ELFCLASS32.
Adding the GCC extension __builtin_frame_address(). We support only zero as the argument for now.
With this functionality, we can implement GCC compatible stdarg by macros in x86-64.
nocode_wanted can't be used to enforce constant expressions, as it is
set f.ex. by __builtin_constant_p.
A null pointer is unequal to a pointer to any object or function.
Assuming symbols always point to memory, a symbol+constant cast to bool
is always true.
Casting of constants was done only inside functions.
I restructured the code and used intermediate types (long double/long long)
for most conversions to have less ifs.
Please review.
There are lots of cases to take care of and lots of mistakes to make.
The return type of a statement expression (a GCC extention) may
involve elements on the symbol stack that have been put there by
the expression. These will be freed at the end of the expression
so that the calling block can not use them.
Contrary to the comment (written in 2003), this bug no longer shows
up in Valgrind, as freed symbols are now put onto a stack for later
reuse.
The ISO C draft allow only signed/unsigned int and _Bool as base type
for bitfields. TinyCC ever since allowed a wider range of types, but
there were many bugs that shifted values when they shouldn't, etc..
The patch introduces a restriction to the layout of bitfields with
mixed types that makes it incompatible with GCC. In
struct {
typeA x:1;
typeB y:1;
};
y is combined with x in the same byte iff typeA is typeB (neglecting
signedness). This is done to avoid alignment issues and exceeding the
width of typeA.
TinyCC sometimes has problems to evaluate constant expressions at
compile time. This leads to code being generated outside of functions.
Without this patch some of these bugs are not caught, because
cur_text_section still points to the section of the last function.
Before the first function cur_text_section is uninitialized.
Setting cur_text_section to a null pointer should make TinyCC die in
all cases.
long long a();
long long b() {
return a();
}
At the end of b there will be some useless register shuffling.
This is because return wants to have the result of a in REG_IRET.
gv checks if this is the case for BOTH registers of the long long.
After this test it uses REG_LRET for the second register if the
first is supposed to be REG_IRET. In other cases it uses RC_INT.
The patch compares the second register against the class it will
have in the end instead of the register class the first register
will have.
At this point I would like to remind those who pick up the patches
that there are two other mails by me with uncommitted fixes:
http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.htmlhttp://lists.gnu.org/archive/html/tinycc-devel/2008-08/msg00007.html
Daniel
This patch adds a switch --with-libgcc to configure.
When passed it prevents libtcc1.a from being built and links to
/lib/libgcc_s.so.1 instead of PREFIX/lib/tcc/libtcc1.a.
It will work on ARM when using libgcc from GCC >= 4.2.0.
Prior versions don't have the __floatun[sd]i[sdx]f functions.
It won't work on i386 because of two missing symbols emitted when
floats are cast to integers, but users can provide those symbols
(global short constants) in their code if needed.
Daniel
This patch is useful for cross compilers. Without this patch tcc
tries to use the host's libraries, crt*.o and include files.
The patch prepends a string to all default paths. The string can
be passed to configure with --sysroot=string.
Daniel
- Builds all four possible ARM targets when cross compiling
- Adds some auto detection to select the target for native ARM builds
The auto detection will select EABI if it finds /lib/ld-linux.so.3.
It will select VFP floating point support when /proc/cpuinfo lists
a VFP or iWMMXt coprocessor. Intel Wireless MMX does not imply VFP,
but it conflicts with FPA, so VFP is the only choice (apart from
yet unsupported soft-float).
Daniel
Yesterday I felt the urge to change a few things in TinyCC.
This is the first and biggest change of all of them.
- use __aeabi_*divmod functions in ARM EABI to make binaries depend
solely on standardized library functions
- refactor ARM floating point <-> integer conversion a bit
- rename long long->float and shift library functions to correspond to
the names used by GCC
- compile more tokens conditionally to reduce the size of TinyCC
The intention is primarily to allow users of the ARM target to use
libgcc (which is usually available as a shared library) instead of
libtcc1 (which can't be compiled for ARM due to lack of an inline
assembler).
Changing the EABI target to use the divmod functions in theory allows
to use it without libtcc1 on any (not necessarily GCC based) ARM EABI
system.
Daniel
- Hanging tcc -E
- Crashes witn global 'int g_i = 1LL;'
- include & lib search paths on win32
Added quick build batch file for mingw
Reverted case label optimization
(See Changelog for details).
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.