Usage example: tcc -xc ex5.cgi
From a gcc docs:
You can specify the input language explicitly with the -x option:
-x language
Specify explicitly the language for the following input files
(rather than letting the compiler choose a default based on the file
name suffix). This option applies to all following input files until
the next -x option. Possible values for language are:
c c-header c-cpp-output
c++ c++-header c++-cpp-output
objective-c objective-c-header objective-c-cpp-output
objective-c++ objective-c++-header objective-c++-cpp-output
assembler assembler-with-cpp
ada
f77 f77-cpp-input f95 f95-cpp-input
java
-x none
Turn off any specification of a language, so that subsequent files
are handled according to their file name suffixes (as they are if -x
has not been used at all)
library Cello: http://libcello.org/ which uses `$` and several
variations of as macros.
There is also RayLanguage which also uses it as a macro for a kind of
ObjC style message passing: https://github.com/kojiba/RayLanguage
This is a patch from Daniel Holden.
This is for a case when no '{' is used in the initialization code.
An option name is -fold-struct-init-code. A linux 2.4.26 can't
find initrd when compiled with a new algorithm.
Lets assume that in *.S files a preprocessor directive
follow '#' char w/o spaces between. Otherwise there is
too many problems with the content of the comments.
- a warning: unnamed struct/union that defines no instances
- allow a nested named struct declaration w/o identifier
only when option -fms-extensions is used
A test program (must be compiled by the above version of the tcc):
/* Tickle a bug in TinyC on 64-bit systems:
* the LSB of the top word or ARGP gets set
* for no obvious reason.
*
* Source: a legacy language interpreter which
* has a little stack / stack pointer for arguments.
*
* Output is: 0x8049620 0x10804961c
* Should be: 0x8049620 0x804961c
*/
#include <stdio.h>
#define NARGS 20000
int ARG[NARGS];
int *ARGSPACE = ARG;
int *ARGP = ARG - 1;
main() { printf("%p %p\n", ARGSPACE, ARGP); }
The common code to move a returned structure packed into
registers into memory on the caller side didn't take the
register size into account when allocating local storage,
so sometimes that lead to stack overwrites (e.g. in 73_arm64.c),
on x86_64. This fixes it by generally making gfunc_sret also return
the register size.
__clear_cache is defined in lib-arm64.c with a single call to
__arm64_clear_cache, which is the real built-in function and is
turned into inline assembler by gen_clear_cache in arm64-gen.c
arm-gen.c: In function `gfunc_call':
arm-gen.c:1202: warning: unused variable `variadic'
arm-gen.c: In function `gfunc_prolog':
arm-gen.c:1258: warning: unused variable `avregs'
arm-gen.c:1340: warning: label `from_stack' defined but not used
arm-gen.c:222: warning: 'default_elfinterp' defined but not used
With this option on a defines are included into the output
(inside comments). This will allow to debug a problems like:
In file included from math.c:8:
In file included from /usr/include/math.h:43:
/usr/include/bits/nan.h:52: warning: NAN redefined
tcc -E -P
do not output a #line directive, a gcc compatible option
tcc -E -P1
don't follow a gcc preprocessor style and do output a standard
#line directive. In such case we don't lose a location info when
we going to compile a resulting file wtith a compiler not
understanding a gnu style line info.
libtcc.c: Add greloca, a generalisation of greloc that takes an addend.
tcc.h: Add greloca and put_elf_reloca.
tccelf.c: Add put_elf_reloca, a generalisation of put_elf_reloc.
tccgen.c: On x86_64, use greloca instead of greloc in init_putv.
This adds parsing of (GCC compatible) visibility attribute
in order to mark selected global symbols as hidden. The generated
.o files contain hidden symbols already, the TCC linker doesn't
yet do the right thing.
Same as with x86_64, disable the runtime_plt_and_got hack
for -run on arm as well. For that we need to handle several
relocations as (potentially) generating PLT slots as well.
Tested with mpfr-3.1.2 and gawk (both using --disable-shared),
there are two resp. five pre-existing problems, so no regressions.
This also works toward enabling real shared libs for arm,
but it's not there yet.
This makes us use the normal PLT/GOT codepaths also for -run,
which formerly used an on-the-side blob for the jump tables.
For x86_64 only for now, arm coming up.
This was going wrong (case TOK_LAND in unary: computed labels)
- vset(&s->type, VT_CONST | VT_SYM, 0);
- vtop->sym = s;
This does the right thing and is shorter:
+ vpushsym(&s->type, s);
Test case was:
int main(int argc, char **argv)
{
int x;
static void *label_return = &&lbl_return;
printf("label_return = %p\n", label_return);
goto *label_return; //<<<<< here segfault on linux X86_64 without the memset on vset
printf("unreachable\n");
lbl_return:
return 0;
}
Also::
- Rename "void* CValue.ptr" to more usable "addr_t ptr_offset"
and start to use it in obvious cases.
- use __attribute__ ((noreturn)) only with gnu compiler
- Revert CValue memsets ("After several days searching ...")
commit 4bc83ac393
Doesn't mean that the vsetX/vpush thingy isn't brittle and
there still might be bugs as to differences in how the CValue
union was set and is then interpreted later on.
However the big memset hammer was just too slow (-3% overall).
This correctly resolves local references to global functions from
shared libs to their PLT slot (instead of directly to the target
symbol), so that interposition works.
This is still not 100% conforming (executables don't export symbols
that are also defined in linked shared libs, as they must), but
normal shared lib situations work.
Introduce a new attribute to check the existence of a PLT entry for a
given symbol has the presence of an entry for that symbol in the dynsym
section is not proof that a PLT entry exists.
This fixes commit dc8ea93b13.
When checking for exact compatibility between types (such as in
__builtin_types_compatible_p) consider the case of default signedness to
be incompatible with both of the explicit signedness for char. That is,
char is incompatible with signed char *and* unsigned char, no matter
what the default signedness for char is.
Refactoring (no logical changes):
- use memcpy in tccgen.c:ieee_finite(double d)
- use union to store attribute flags in Sym
Makefile: "CFLAGS+=-fno-strict-aliasing" basically not necessary
anymore but I left it for now because gcc sometimes behaves
unexpectedly without.
Also:
- configure: back to mode 100755
- tcc.h: remove unused variables tdata/tbss_section
- x86_64-gen.c: adjust gfunc_sret for prototype
- tccgen: error out for cast to void, as in
void foo(void) { return 1; }
This avoids an assertion failure in x86_64-gen.c, also.
also fix tests2/03_struct.c accordingly
- Error: "memory full" - be more specific
- Makefiles: remove circular dependencies, lookup tcctest.c from VPATH
- tcc.h: cleanup lib, include, crt and libgcc search paths"
avoid duplication or trailing slashes with no CONFIG_MULTIARCHDIR
(as from 9382d6f1a0)
- tcc.h: remove ";{B}" from PE search path
in ce5e12c2f9 James Lyon wrote:
"... I'm not sure this is the right way to fix this problem."
And the answer is: No, please. (copying libtcc1.a for tests instead)
- win32/build_tcc.bat: do not move away a versioned file
The procedure calling standard for ARM architecture mandate the use of
the base standard for variadic function. Therefore, hgen float aggregate
must be returned via stack when greater than 4 bytes and via core
registers else in case of variadic function.
This patch improve gfunc_sret() to take into account whether the
function is variadic or not and make use of gfunc_sret() return value to
determine whether to pass a structure via stack in gfunc_prolog(). It
also take advantage of knowing if a function is variadic or not move
float result value from VFP register to core register in gfunc_epilog().
Commit 9382d6f1 ("Fix lib, include, crt and libgcc search paths",
07-09-2013) inadvertently included an initial empty entry to the
CONFIG_TCC_SYSINCLUDEPATHS variable (for non win32 targets). In
addition to an empty line in the 'tcc -vv' display, this leads
to the preprocessor attempting to read an include file from the
root of the filesystem (i.e. '/header.h').
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Use one more bit in AttributeDef to differenciate between declared
function (only its prototype is known) and defined function (its body is
also known). This allows to generate an error in cases like:
int f(){return 0;}
int f(){return 1;}
- Use runtime function for conversion
- Also initialize fp with tcc -run on windows
This fixes a bug where
double x = 1.0;
double y = 1.0000000000000001;
double z = x < y ? 0 : sqrt (x*x - y*y);
caused a bad sqrt because rounding precision for the x < y comparison
was different to the one used within the sqrt function.
This also fixes a bug where
printf("%d, %d", (int)pow(10, 2), (int)pow(10, 2));
would print
100, 99
Unrelated:
win32: document relative include & lib lookup
win32: normalize_slashes: do not mirror silly gcc behavior
This reverts part of commit 8a81f9e103
winapi: add missing WINAPI decl. for some functions
VLA storage is now freed when it goes out of scope. This makes it
possible to use a VLA inside a loop without consuming an unlimited
amount of memory.
Combining VLAs with alloca() should work as in GCC - when a VLA is
freed, memory allocated by alloca() after the VLA was created is also
freed. There are some exceptions to this rule when using goto: if a VLA
is in scope at the goto, jumping to a label will reset the stack pointer
to where it was immediately after the last VLA was created prior to the
label, or to what it was before the first VLA was created if the label
is outside the scope of any VLA. This means that in some cases combining
alloca() and VLAs will free alloca() memory where GCC would not.
All tests pass. I think I've caught all the cases assuming only XMM0 is
used. I expect that Win64 is horribly broken by this point though,
because I haven't altered it to cope with XMM1.
There are probably still issues on x86-64 I've missed.
I've added a few new tests to abitest, which fail (2x long long and 2x double
in a struct should be passed in registers).
abitest now passes; however test1-3 fail in init_test. All other tests
pass. I need to re-test Win32 and Linux-x86.
I've added a dummy implementation of gfunc_sret to c67-gen.c so it
should now compile, and I think it should behave as before I created
gfunc_sret.
I expect that Linux-x86 is probably fine. All other architectures
except ARM are definitely broken since I haven't yet implemented
gfunc_sret for these, although replicating the current behaviour
should be straightforward.
Only one test so far, which fails on Windows (with MinGW as the native
compiler - I've tested the MinGW output against MSVC and it appears the
two are compatible).
I've also had to modify tcc.h so that tcc_set_lib_path can point to the
directory containing libtcc1.a on Windows to make the libtcc dependent
tests work. I'm not sure this is the right way to fix this problem.